ZOJ 1060 Sorting It All Out (POJ1094) (拓扑排序)

其实这题是我拿到这些题时,第一道仔细看的题(当然我开始没有看到过的人数只有100……),第一反应是拓扑排序,可是后来发现传统拓扑排序过不了,因为这道题要求图的联通,于是想当然的加了个并查集函数,敲完交上就WA了,再仔细看,发现题目要求输出的序列是唯一的,而拓扑排序并不是稳定排序,所以直接拓扑的肯定不行。

 

我的处理方案(其实是大神刘超的处理方案)是:

找到第一个入度为0的点,以它为起点,更新所有点入度值,接下来,只在和这个起点相邻的点里面重复以上的操作,这样如果能够得到一个拓扑序列,那么就一定是唯一的,而且符合题目要求。

 

当然题目中还有一些注意的地方:

 

1,判断是否完成拓扑排序时,要看所有点是否都已经在当前所得拓扑序列中,如果没有包含所有点,那么即使toposort()返回值是1,也要继续构图。

 

2,用floyd的判环其实不如用topo做(当然要领写一个topo()),我用floyd比较习惯了,所以没改

 

这题在POJ的discuss里面有测试数据,据说是后台数据……真的很强大,过了那个,应该就能A的

 

#include<stdio.h> #include<string.h> #define N 100 int map[N][N],ret[N]; int n; int floyd() { int i,j,k; for(k=0;k<n;k++) { for(i=0;i<n;i++) for(j=0;j<n;j++) map[i][j]=map[i][j]||map[i][k]&&map[k][j]; } for(i=0;i<n;i++) if(map[i][i])return 0; //有环 return 1; //无环 } int toposort() { int d[N],i,j,k,cur; for(i=0;i<n;i++)//计算入度 { d[i]=0; for(j=0;j<n;j++) d[i]+=map[j][i]; } for(k=0;k<n;k++) //找第一个入度为0的点 { if(d[k]==0) { cur=k;break; } } if(cur==n)return 0; ret[0]=cur; d[cur]=-1; for(k=1;k<n;k++) { for(j=0;j<n;j++)//更新入度 d[j]-=map[cur][j]; for(i=0;i<n;i++)//找和cur点相连,且入度为0的点 { if(map[cur][i]==1 && d[i]==0) break; } if(i==n)return 0; //没找到,返回0,无法完成排序 ret[k]=i; //保存找到的点 d[i]=-1; //删除该点 cur=i; } return 1; //可排 } int main() { int i,j,m,huan,xu,phuan,pxu,used[N],cnt; char str[4]; while(scanf("%d%d",&n,&m),n+m) { phuan=pxu=huan=xu=0; memset(map,0,sizeof(map)); memset(used,0,sizeof(used)); for(cnt=0,i=1;i<=m;i++) { scanf("%s",str); for(j=0;j<n;j++) { if(!used[str[0]-'A']){cnt++;used[str[0]-'A']=1;} if(!used[str[2]-'A']){cnt++;used[str[2]-'A']=1;} } map[ str[0]-'A' ][ str[2]-'A' ]=1; if(huan) continue; //有环 if(xu) continue; //已经完成排序 if(!floyd()) { huan=1; phuan=i; } if( toposort() && cnt==n) { xu=1; pxu=i; } } if(xu) { printf("Sorted sequence determined after %d relations: ",pxu); for(i=0;i<n;i++) printf("%c",'A'+ret[i]); } else if(huan) printf("Inconsistency found after %d relations",phuan); else printf("Sorted sequence cannot be determined"); puts("."); } return 0; } 

你可能感兴趣的:(ZOJ 1060 Sorting It All Out (POJ1094) (拓扑排序))