一个简单的求拓扑排序的算法:首先要找到任意入度为0的一个顶点,删除它及所有相邻的边,再找入度为0的顶点,以此类推,直到删除所有顶点。顶点的删除顺序即为拓扑排序。但这一题有点不同,不能有并列结构的拓扑。所以每次都要判断入度为0的个数,如果个数为0则是环。如果个数大于1,则先记录这是有并列的拓扑,因为可能存在有并列也有环的情况。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string.h>
using namespace std;
const int N=27;
int mp[N][N],u[N*N],v[N*N];
int n,m,in[N];
char str[N];
int TopoSort(){
int d[N],cnt=0,flag=0;
memcpy(d,in,sizeof in);//d是入度
for(int i=0;i<n;i++){
int next=n,num=0;//统计入度为0个数
for(int j=0;j<n;j++)
if(d[j]==0)
next=j,num++;
if(num==0) return -1;//成环
if(num>1) flag=1;//并列--不能直接返回
d[next]=-1;//next进入排序队列,删除相关入度
str[cnt++]=next+'A';
for(int j=0;j<n;j++)
if(mp[next][j]==1)
d[j]--;
}
str[cnt]=0;
if(flag) return 0;//排序不完全
return 1;//完全排序
}
int main(){
while(cin>>n>>m){
if(n==0&&m==0) break;
memset(mp,0,sizeof mp);
memset(in,0,sizeof in);
for(int i=0;i<m;i++){//存储边
scanf("%s",str);
u[i]=str[0]-'A';
v[i]=str[2]-'A';
}
int ok=0;
for(int i=0;i<m;i++){
mp[u[i]][v[i]]=1;
in[v[i]]++;
int mark=TopoSort();
if(mark==-1){
printf("Inconsistency found after %d relations.\n",i+1);
ok=1;break;
}
else if(mark==1){
printf("Sorted sequence determined after %d relations: %s.\n",i+1,str);
ok=1;break;
}
}
if(ok==0) printf("Sorted sequence cannot be determined.\n");
}
return 0;
}