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