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;
}
}