zoj1060Sorting It All Out

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=60

拓扑排序

0度>1多解

0度==1正常

0度==0矛盾

#include<iostream>
#include<stdio.h>
#include<queue>
#include<string>
#include<algorithm>
#include<cstring>
using namespace std;
int vis[30],d[30],adj[30][30];
int m,n,flag,ok,pos;
string path;
void topo()
{
	 memset(d,0,sizeof(d));
	queue <int > q;
	while(!q.empty())q.pop();
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
		{
			if(adj[j][i])d[i]++;
		}

	for(int i=0;i<n;i++)
		if(vis[i]&&!d[i])q.push(i);//将度数为0的点存入队列

	if(q.empty()){flag=2;return;}//0度点为0,则存在环,矛盾,结束
	if(q.size()>1){flag=1;}//多解但不排除矛盾,所以这里不能结束
   
	path="";
	while(!q.empty())
	{
		int tmp=q.front();
		q.pop();
		path+=char(tmp+'A');
		for(int j=0;j<n;j++)
			if(adj[tmp][j])
			{
				d[j]--;
				if(!d[j])q.push(j);
			}	
		if(q.size()>1){flag=1;}//多解不排除矛盾
	}
	int cnt=0;
	for(int i=0;i<n;i++)
	{
          if(vis[i])cnt++;//统计已出现的字母个数
	}
	if(path.size()==n&&!flag){flag=3;return;}
	if(path.size()<n&&cnt==n){flag=2;return;}
	if(cnt<n){flag=1;return;}

}
int main()
{
	string s;
    while(cin>>n>>m&&n&&m)
	{
	  
		memset(vis,0,sizeof(vis));
        memset(adj,0,sizeof(adj));
		ok=0;
		for(int i=0;i<m;i++)
		{
             cin>>s;
			 if(!ok)
			 {
				
				 flag=0;
				 int f1=s[0]-'A',f2=s[2]-'A';
				 vis[f1]=1,vis[f2]=1;
				 adj[f1][f2]=1;
				 flag=0;
				 topo();
				 if(flag==2||flag==3){pos=i+1;ok=1;}

			 }
             
		}
		if(flag==3)cout<<"Sorted sequence determined after "<<pos<<" relations: "<<path<<"."<<endl;
		if(flag==2)cout<<"Inconsistency found after "<<pos<<" relations."<<endl;
		if(flag==1)cout<<"Sorted sequence cannot be determined."<<endl;
	}
}
原文地址:https://www.cnblogs.com/sook/p/2016678.html