poj1094

题目大意:

     给出多组字母之间大小关系,判断是否存在一个绝对的顺序排列


解题思路:

这依然是道拓扑排序的题目,需要注意因为题目要求输出判断出具体顺序的条件序号,所以我们每读入一个条件就需要进行一次拓扑排序

还需注意拓扑排序时需要注意是否有环


#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;

#define alph 26

int N,M;
int graph[alph][alph] = {};
int degree[alph] = {};
int degreeTmp[alph] = {};
int result[alph] = {};

//-----------------------------
// 拓扑排序
// 
// 每次寻找一个入度为0的点,加入结果队列
// 如果某次包括多个入度为0的点则表示还不能确定顺序
// 但还是要继续下去,因为要判断是否包含环
//-----------------------------
int TopologicalSorting()
{
	int j = 0;
	int count;
	int flag;
	int returnValue = 0;

	memset(result,0,sizeof(result));
	memcpy(degreeTmp,degree,sizeof(degree));

	for(int j=0;j<N;j++)
	{
		count = 0;
		flag = 0;
		for(int i=0;i<N;i++)
			if(degreeTmp[i] == 0)
			{
				count++;
				flag = i;
			}
		
		if(count == 0)			//有环
			return 2;
		else if(count > 1)		// 没绝对顺序
			returnValue = 1;

		result[j] = flag;

		// 修改degree
		degreeTmp[flag] = -1;

		for(int i=0;i<N;i++)
			if(graph[flag][i] == 1)
				degreeTmp[i]--;
	}
	
	return returnValue;
}

int main()
{
	while(cin >> N >> M
		&& (N | M) )
	{
		memset(graph,0,sizeof(graph));
		memset(degree,0,sizeof(degree));

		bool toContinue = false;
		for(int i = 0;i < M;i++)
		{
			char in,out,tmp;
			cin >> in >> tmp >> out;

			if(toContinue)
				continue;
			
			// 更新图信息
			graph[(int)(out-'A')][(int)(in-'A')] = 1;
			degree[(int)(in-'A')]++;

			int returnValue = TopologicalSorting();
			if(returnValue == 0)			//找到顺序
			{
				cout << "Sorted sequence determined after "<<i+1<<" relations: ";
				for(int j=N-1;j>=0;j--)
					cout <<(char)(result[j]+'A');
				cout << "."<<endl;
				toContinue = true;
			}
			else if(returnValue == 1)	// 没找到绝对顺序
			{
				// do nothing
			}
			else					// 有环
			{
				cout <<"Inconsistency found after "<<i+1<<" relations."<<endl;
				toContinue = true;
			}
		}

		if(!toContinue)
			cout << "Sorted sequence cannot be determined."<<endl;
	}
	
	return 0;
}


你可能感兴趣的:(poj)