zoj 1060 || poj 1094 Sorting It All Out(拓扑排序)

拓扑排序。 = =。

 

我就因为要应付考试,所以看了看。顺便还看了AOE网,考试居然出中了,大幸。。。

 

觉得这个也不难啊,拓排。把入度为0的点删掉,把它出的边删掉,连接的顶点的入度减1,一直这样。。。

 

 

这个题。好吧。我承认开始没看懂意思。结果做完之后一直很纳闷。poj的disscuss很强大。看了人家思路。终于理解啥意思了。T T。

 

边是一条一条读的,如果读到某条边就找到环(即矛盾了),就记录这个边,输出矛盾。

 

如果把边读完,仍不能排序,输出不能排序。

 

如果读到某条边可以把它全部排列完的话,就输出边的标号,以及排好的顺序。

 

基本按人家代码写的,表示惭愧。

 

学习到几点,用floyd找环很好用。

 

 

#include <stdio.h> #include <stdlib.h> #include <iostream> #include <string.h> using namespace std; int map[27][27]; char output[27]; int num,n; int Floyd() //判断是否有环。 { int i,k,j; for(i=0; i<n; i++) for(k=0; k<n; k++) for(j=0; j<n; j++) if( map[k][i] && map[i][j] ) map[k][j] = 1; for(i=0; i<n; i++) if( map[i][i] == 1 ) return 1; return 0; } int Topsort() { int cou,ind,k,i; int degree[27]; int used[27]; num = 0; memset(used,0,sizeof(used)); //标记出度为0的点是否已经用过了。 memset( degree,0,sizeof(degree) );// 存出度。 for(i=0; i<n; i++) for(k=0; k<n; k++) if( map[i][k] ) // 存出度。 degree[k]++; for(i=0; i<n; i++) { cou = 0; for(k=0; k<n; k++) if( degree[k] == 0 && !used[k] ) { output[num++] = k + 'A'; used[k] = 1; cou++; ind = k; } if( cou > 1 ) return 0; // 这个可能边没读完,判断不出来什么,所以继续读边。 if( cou == 0 ) return 1; // 这个其实没用。上面已经判过环了。 for(k=0; k<n; k++) if( map[ind][k] ) degree[k]--; } output[num] = '/0'; return 2; // 当经过n次循环到达这里,说明都排好序了。 } int main() { int m; int i,pos; char str[4]; int flag; while( scanf("%d%d",&n,&m)!=EOF && ( n || m ) ) { flag = 0; memset(map,0,sizeof(map)); for(i=0; i<m; i++) { scanf("%s",str); map[str[0]-'A'][str[2]-'A'] = 1; if( flag != 0 ) continue; // 如果不为0,下面都没必要进行了。 flag = Floyd(); if( flag == 1 ) pos = i; if( flag == 0 ) flag = Topsort(); else // 不能继续。。。如果继续的话,pos保存的位置可能就被改变啦。 continue; if( flag == 2 ) pos = i; } pos++;//因为我循环是从0开始的,所以要加1。。。 if( flag == 2 ) { printf("Sorted sequence determined after %d relations: %s./n",pos,output); continue; } if( flag == 1 ) { printf("Inconsistency found after %d relations./n",pos); continue; } printf("Sorted sequence cannot be determined./n"); } return 0; }

你可能感兴趣的:(IM,output,sorting)