POJ 1094 Sorting It All Out 拓扑排序 +floyd!
题意很容易理解,就是拓扑排序 实现起来不容易,起码我觉得是这样
首先 用拓扑排序检查是否有环 如果没环路 再用floyd传递闭包 (传递闭包 好专业的术语喔),再判断序列是否唯一
学了一下拓扑排序,不难,就是先算出每个点的入度 ,找出入度为0 ,比如 i 作为第一个,然后比如map[i][j]==1 i,j 之间存在 i->j的边
则从cnt[j]--,即 j 的入度减一 然后再找入度为0的点。。。
floyd传递闭包 判断序列是否唯一的方法!
代码:
#include<iostream> #include<cstdio> #include<string> #include<cstring> using namespace std; int map[30][30],visit[30],cnt[30],path[30]; int n; bool topsort() { int i,j,k; memset(cnt,0,sizeof(cnt)); for(i=0;i<n;i++) for(j=0;j<n;j++) cnt[j]+=map[i][j]; for(i=0;i<n;i++) { for(k=0;k<n;k++) if(cnt[k]==0)break; if(k==n)return false;//有环 for(j=0;j<n;j++) if(map[k][j])cnt[j]--; path[i]=k; cnt[k]-=1; } return true; } int main() { int m,t,i,j,k; char ch[5]; bool output; while(~scanf("%d%d",&n,&m)) { output=false; if(n==0&&m==0)break; memset(map,0,sizeof(map)); for(t=1;t<=m;t++) { scanf("%s",&ch); if(output)continue;//只需输入 i=ch[0]-'A'; j=ch[2]-'A'; if(map[i][j])continue;//如果已经判断过 无需重复 map[i][j]=1; if(!topsort())//如果有环 { printf("Inconsistency found after %d relations.\n",t); output=true; continue; } for(k=0;k<n;k++) for(i=0;i<n;i++) for(j=0;j<n;j++) if(map[i][k]&&map[k][j]) map[i][j]=1; bool visit[30],flag=true; memset(visit,0,sizeof(visit));//开始还漏了WA int SUM; for(i=0;i<n;i++) { SUM=0; for(j=0;j<n;j++) { if(map[i][j]) SUM++; } if(visit[SUM]){flag=false; break;} visit[SUM]=true; } if(flag) { printf("Sorted sequence determined after %d relations: ",t); for(i=0;i<n;i++) printf("%c",path[i]+'A'); printf(".\n"); output=true; } } if(!output) printf("Sorted sequence cannot be determined.\n"); } return 0; }