HDU 1285确定比赛名次(拓补排序)
确定比赛名次
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 5871 Accepted Submission(s): 2190
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
View Code
1 #include<stdio.h> 2 #include<string.h> 3 int a[505][505],topo[505],de[505]; 4 void po(int n) 5 { 6 int i,j,k; 7 for(i=1;i<=n;i++) 8 for(j=1;j<=n;j++) 9 { 10 if(de[j]==0)//入度为0的点 11 { 12 de[j]--;//标记正在找的 13 topo[i]=j;//删除,存入topo 14 for(k=1;k<=n;k++)//更新前度节点为j的入度 15 { 16 if(a[j][k]==1) 17 de[k]--; 18 } 19 break; 20 } 21 } 22 } 23 int main() 24 { 25 int m,n,i,x,y; 26 27 while(~scanf("%d %d",&m,&n)) 28 { 29 memset(a,0,sizeof(a)); 30 memset(de,0,sizeof(de)); 31 for(i=1;i<=n;i++) 32 { 33 scanf("%d %d",&x, &y); 34 if(a[x][y]==0) 35 { 36 a[x][y]=1; 37 de[y]++; 38 } 39 } 40 po(m); 41 for(i=1;i<m;i++) 42 printf("%d ",topo[i]); 43 printf("%d\n",topo[m]); 44 } 45 return 0; 46 }