PKU 1094 Sorting It All Out(拓扑排序)
题目大意:就是给定一组字母的大小关系判断他们是否能组成唯一的拓扑序列。
是典型的拓扑排序,但输出格式上确有三种形式:
1.该字母序列有序,并依次输出;
2.判断该序列是否唯一;
3.该序列字母次序之间是否有矛盾,即是否有环存在;
而这三种形式的判断是有顺序的:先判断(3)是否有环,再判断是否有序(1),最后才能判断是否能得出结果(2)。注意:对于(2)必须遍历完整个图,而(1)和(3)一旦得出结果,对后面的输入就不用做处理了。
#include<cstdio> #include<cstring> char alp[27]; int edge[27][27],in[27]; int TopoSort(int n) { int t=0,tmp[27],flag=1; for(int i=1;i<=n;i++) tmp[i]=in[i]; for(int i=1;i<=n;i++){ int in0=0,loc;//查找入度为零的顶点个数 for(int j=1;j<=n;j++){ if(tmp[j]==0){ in0++; loc=j; } } if(in0==0) return 0;//有环,那么后面的就不用再判断了 if(in0>1) flag=-1;//不确定,但不能直接return -1;因为后面的字母中还可能形成环而return 0; alp[t++]='A'+loc-1;//入度为零的字母入队 tmp[loc]=-1; for(int k=1;k<=n;k++) if(edge[loc][k]==1) tmp[k]--; } return flag; } //flag=1:有序 flag=-1:不确定 int main() { int m,n,x,y; char str[5]; while(scanf("%d%d",&n,&m),n|m){ memset(edge,0,sizeof(edge)); memset(in,0,sizeof(in)); bool sign=0; for(int i=1;i<=m;i++){ scanf("%s",str); if(sign) continue; //一旦得出结果,对后续的输入不做处理,但是不能break,因为还得继续输入 x=str[0]-'A'+1; y=str[2]-'A'+1; edge[x][y]=1; in[y]++; int flag=TopoSort(n); if(flag==0){//有环 printf("Inconsistency found after %d relations.\n",i); sign=1; } if(flag==1){//有序 printf("Sorted sequence determined after %d relations: ",i); for(int j=0;j<n;j++) printf("%c",alp[j]); printf(".\n"); sign=1; }//当sign=1时表明已得出结果 } if(!sign) //不确定 printf("Sorted sequence cannot be determined.\n"); } return 0; }