POJ 1094 Sorting It All Out

Sorting It All Out
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 22173 Accepted: 7647

Description

An ascending sorted sequence of distinct values is one in which some form of a less-than operator is used to order the elements from smallest to largest. For example, the sorted sequence A, B, C, D implies that A < B, B < C and C < D. in this problem, we will give you a set of relations of the form A < B and ask you to determine whether a sorted order has been specified or not.

Input

Input consists of multiple problem instances. Each instance starts with a line containing two positive integers n and m. the first value indicated the number of objects to sort, where 2 <= n <= 26. The objects to be sorted will be the first n characters of the uppercase alphabet. The second value m indicates the number of relations of the form A < B which will be given in this problem instance. Next will be m lines, each containing one such relation consisting of three characters: an uppercase letter, the character "<" and a second uppercase letter. No letter will be outside the range of the first n letters of the alphabet. Values of n = m = 0 indicate end of input.

Output

For each problem instance, output consists of one line. This line should be one of the following three:

Sorted sequence determined after xxx relations: yyy...y.
Sorted sequence cannot be determined.
Inconsistency found after xxx relations.

where xxx is the number of relations processed at the time either a sorted sequence is determined or an inconsistency is found, whichever comes first, and yyy...y is the sorted, ascending sequence.

Sample Input

4 6
A<B
A<C
B<C
C<D
B<D
A<B
3 2
A<B
B<A
26 1
A<Z
0 0

Sample Output

Sorted sequence determined after 4 relations: ABCD.
Inconsistency found after 2 relations.
Sorted sequence cannot be determined.

Source

解题思路:拓扑排序的题,首先明确存在以下几种情况:
1.根据已知条件构成的图中存在环,就是说存在逻辑矛盾,这个用Warshall算法判定关系序偶集合中有无传递闭包,有就是存在环。
2.根据已知条件构不成完全图,就是字母数不足,这样就没办法组成拓扑序列。
3.根据已知条件构成的图中有不只一的点的入度为0,这样组成的拓扑序列就不唯一。
4.根据已知条件构成的图,可以组成唯一的拓扑序列。
以上2,3,4条的关键判定条件为是否图中所有点的出入度之和均为顶点数减1,若是的话,则证明有唯一的拓扑序列存在。
#include<iostream>
#include<queue>
using namespace std;
int map[30][30],indegree[30],outdegree[30],num[30],m,n;
bool deleted[30];
char topo[30];
bool Warshall()
//计算关系集合中有无传递闭包,有的话就说明关系间存在矛盾
{
	int i,j,k;
	for(k=0;k<n;k++)
		for(i=0;i<n;i++)
			for(j=0;j<n;j++)
				if(map[i][k]&&map[k][j])
					map[i][j]=1;
	for(i=0;i<n;i++)
		if(map[i][i])
			return true;
	return false;
}
bool Calculate()
{
	int i,j;
	memset(indegree,0,sizeof(indegree));
	memset(outdegree,0,sizeof(outdegree));
	for(i=0;i<n;i++)
		for(j=0;j<n;j++)
			//计算图中顶点的度数
			if(map[i][j])
			{
				indegree[j]++;
				outdegree[i]++;
			}
	for(i=0;i<n;i++)
		if(indegree[i]+outdegree[i]!=n-1)//判断根据已有关系是否能构成一幅完整的图且该图中入度为0的点只有一个
			return false;
	return true;
}
void Topo_sort()
{
	int i,j=0,k=0;
	queue <int> q;
	memset(deleted,false,sizeof(deleted));
	for(i=0;i<n&&k<=1;i++)
		if(!indegree[i])//将没有入度的点作为拓扑序列的第一个入队,同时保证这样的点只有一个
			{
				q.push(i);
				k++;
		    }
	while(!q.empty())
	{
		int t=q.front();
		q.pop();
		deleted[t]=true;//将队列中的点写入拓扑序列,同时将这一点从图中删除
		topo[j++]=t+'A';
		for(i=0;i<n;i++)
			if(!deleted[i])
			//对于图中剩下的点
			{
				if(map[t][i])//若有入度是刚才删去点所发出,删去这一条边
					indegree[i]--;
		        if(indegree[i]==0)//若删去后使得该点入度为0,将此点加入拓扑序列
					q.push(i);
			}
	}
	topo[j]='\0';
}
int main()
{
	int i,flag1,flag2;
	char relation[3];
	while(cin>>n>>m&&(m||n))
	{
		memset(map,0,sizeof(map));
		flag1=flag2=0;
		for(i=1;i<=m;i++)
		{
			cin>>relation;
			map[relation[0]-'A'][relation[2]-'A']=1;//根据题目所给关系构图,用来表示前者到后者的一条有向边
			if(flag1||flag2)  continue;//根据已输入关系可以判断可否构成拓扑序列,后续输入就无意义了
			if(Warshall())
			//不能构成拓扑序列且关系间存在矛盾
			{
				flag1=i;
				continue;
			}
			else if(Calculate())
            //能构成拓扑序列且只有唯一一个拓扑序列
			{
				Topo_sort();
				flag2=i;
			}
		}
			if(flag1)
				cout<<"Inconsistency found after "<<flag1<<" relations.\n";
			else if(flag2)
				cout<<"Sorted sequence determined after "<<flag2<<" relations: "<<topo<<".\n";
			else
				cout<<"Sorted sequence cannot be determined.\n";//拓扑序列不唯一
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值