拓扑排序
花了一节课多的时间看完了拓扑排序的基本模板,顺带做了注解,终于理解了这个算法的实现。本题找每一层的结点的时候是按照从上向下,从左往右的顺序删除的,因为输入的时候已经确定了数据的大小关系,也就是在寻找入度为零的点的时候是从小到大检索的,如果从大往小检索,就会先深入一侧,再横向搜索,就像树的深度搜索一样?。。(表示疑惑)。。
下面给出题目
确定比赛名次
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7059 Accepted Submission(s): 2674
Problem Description
有N个比赛队(1<=N<=500),编号依次为1,2,3,。。。。,N进行比
赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1赢P2,用
P1,P2表示,排名时P1在P2之前。现在请你编程序确定排名。
Input
输入有若干组,每组中的第一行为二个数N(1<=N<=500),M;其中N表示队伍的个数,M表示接着有M行的输入数据。接下来的M行数据中,每行也有两个整数P1,P2表示即P1队赢了P2队。
Output
给出一个符合要求的排名。输出时队伍号之间有空格,最后一名后面没有空格。
其他说明:符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前;输入数据保证是正确的,即输入数据确保一定能有一个符合要求的排名。
其他说明:符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前;输入数据保证是正确的,即输入数据确保一定能有一个符合要求的排名。
Sample Input
4 3
1 2
2 3
4 3
Sample Output
1 2 4 3
1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 #include<algorithm> 5 using namespace std; 6 #define maxx 505 7 //degree[] 每个结点的入度 8 //f[] 每个结点所在的层 9 int degree[maxx]; 10 int f[maxx]; 11 int top; 12 int map[maxx][maxx]; 13 int n,m; 14 struct node 15 { 16 int p; 17 int top; 18 } po[maxx]; 19 void Toplogical_sort() 20 { 21 int i,j; 22 bool p=true;还有数据可以操作 23 top=0;处于第几个层次 24 int tmp;当前位置 25 while(p)如果还有可以操作的 26 { 27 p=false;把这个点去掉 28 top++;到下一层 29 tmp=0;暂时的tmp,为了跳出循环还有i存在 30 for(i=1; i<=n; i++)循环找入度为零的点 31 if(degree[i]==0)找到 32 { 33 p=true;修改成有数据可以继续操作 34 f[i]=top;当前数据在第几层 35 tmp=i;tmp改成当前数据推出 36 break; 37 } 38 for(j=1; j<=n; j++)找该点的后继有向箭头 39 if(map[tmp][j])找到 40 degree[j]--;入度减一 41 degree[tmp]=-1;把当前结点置负,也就是消失 42 } 43 top--;没有入度为零的点了,都是负一了,要把最后一个加上多余的一层去掉,最后一个循环什么都没做但是top加1了 44 } 45 int cmp(struct node a,struct node b) 46 { 47 return a.top<b.top; 48 } 比较层次的大小 49 int main() 50 { 51 while(scanf("%d%d",&n,&m)!=EOF) 52 { 53 memset(map,0,sizeof(map)); 54 memset(degree,0,sizeof(degree)); 55 memset(f,0,sizeof(f));清空 56 int a,b; 57 for(int i=1; i<=m; i++)循环输入数值 58 { 59 scanf("%d%d",&a,&b); 60 if(!map[a][b]) 61 { 62 map[a][b]=1;置为真 63 degree[b]++;确定有几个入度 64 } 65 }全都输入完毕 66 Toplogical_sort();进行拓扑排序,将入度逐一删除,并确定每个数据的层次 67 for(int i=0; i<n; i++) 68 { 69 po[i].p=i+1; 70 po[i].top=f[i+1]; 71 }赋值层次和数据,方便排序 72 sort(po,po+n,cmp);用sort排序,从小到大排序,层次越低越先 73 for(int i=0; i<n-1; i++) 74 printf("%d ",po[i].p); 75 printf("%d\n",po[n-1].p);输出 76 } 77 return 0; 78 }
模板来自http://blog.csdn.net/sdjzli/article/details/8639236
感谢!