POJ 1094 Sorting It All Out 拓扑排序

Sorting It All Out
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 21042 Accepted: 7226

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


看上去不就是喜闻乐见的拓扑排序?

看上去是个在线算法...实际上一点都不省时间...每次都是暴力判断是否拓扑

但在判断成环的情况时错了一个小地方,导致DEBUG了一整天...看来还是代码功力不够...敲的时候开小差...敲完以后就悲剧了...

而且我的代码复杂度奇高达到了N^4...绝对不是一个好的算法...好在数据量比较小...

本来拓扑排序邻接表的时候复杂度就是N^2了...之后我在判断是否成环的时候又用了一次N^2...结果很是悲剧...用了94MS

这代码纯属贴一下...可以用优先队列处理...复杂度能降到N+M

#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
using namespace std;
//int max(int x,int y){return x>y?x:y;}
//int min(int x,int y){return x<y?x:y;}
char order[27];
int track[27];
int judge(int x[][27],int y[],int m)
{
	int i,j,count=0,trackx=0;
	int p[27][27],q[27],tra[27];
	memset(tra,0,sizeof(tra));
	for(i=1;i<=m;i++)
		for(j=1;j<=m;j++)
			p[i][j]=x[i][j];
	for(i=1;i<=m;i++)
		q[i]=y[i];
	for(i=1;i<=26;i++)
	{	
		if(q[i]==0 && tra[i]==0)
		{
			int xx=0;
			tra[i]=1;
			for(j=1;j<=m;j++)
			{
				if(p[i][j]==1)
				{
					p[i][j]=0;
					q[j]--;
					xx=1;
				}
			}
			if(xx) i=0;
		}
	}
	for(j=1;j<=m;j++)
		if(q[j]>0 && tra[j]==0)
			trackx=1;
	if(i==27 && trackx==1)
		return -1;//有环
	for(i=1;i<=m;i++)
		if(y[i]==0 && track[i]==0 )
			count++;
	if(count>1)
		return 0;//不能确定序列
	else if(count==0)
		return -1; //有环	
	else return 1;//可以一搞
}
int topsort(int p[][27],int q[],int m)
{
	int x[27][27],y[27];
	int nx=0;
	int i,j;
	for(i=1;i<=m;i++)
		for(j=1;j<=m;j++)
			x[i][j]=p[i][j];
	for(i=1;i<=m;i++)
		y[i]=q[i];
	memset(order,0,sizeof(order));
	memset(track,0,sizeof(track));
	for(i=1;i<=1000;i++)
	{
		if(nx==m)
			return 1; //成功
		if(judge(x,y,m)==-1)	return -1;
		if(judge(x,y,m)==0)	return 0;	
		if(y[i]==0 && track[i]==0)
		{			
			order[nx]=i+'A'-1;
			nx++;		
			track[i]=1;
			for(j=1;j<=m;j++)
			{
				if(x[i][j]!=0)
				{
					x[i][j]=0;
					y[j]--;
				}
			}
			for(j=1;j<=m;j++)
			{
				if(y[j]==0 && track[j]==0)
				{
					i=j-1;
					break;
				}
			}
		}
	}	
	return 0;
}
int main()
{
//	freopen("in.txt","r",stdin);
	int m,n;
	while(cin>>m>>n && m!=0 && n!=0)
	{
		int i,j,k;
		int map[27][27];
		int num[27];
		memset(order,0,sizeof(order));
		memset(map,0,sizeof(map));
		memset(num,0,sizeof(num));
		for(i = 1 ; i <= n ; i++ )
		{
			char a,ch,b;
			cin>>a>>ch>>b;
			map[b-'A'+1][a-'A'+1]=1;
			num[a-'A'+1]++;
			if(topsort(map,num,m)==1)
			{
				for(j=i+1;j<=n;j++)
					cin>>a>>ch>>b;
				printf("Sorted sequence determined after %d relations: ",i);
				for(j=26;j>=0;j--)
					if(order[j]>='A'&&order[j]<='Z')
						cout<<order[j];
				cout<<"."<<endl;
				break;
			}
			if(topsort(map,num,m)==-1)
			{
				for(j=i+1;j<=n;j++)
					cin>>a>>ch>>b;
				printf("Inconsistency found after %d relations.\n",i);
				break;
			}	
		}
		if(i==n+1)
			printf("Sorted sequence cannot be determined.\n");
	}
    return 0;
}



posted @ 2012-08-03 17:19  Felix_F  阅读(132)  评论(0编辑  收藏  举报