HDU 1285确定比赛名次
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1285
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<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stack> 6 #include<math.h> 7 #include<queue> 8 #include<map> 9 using namespace std; 10 int ans[510][510];//记录两人是否进行了比赛 11 int n,indegree[510];//记录前驱个数 12 int q[510];//保存拓扑 13 void tuopu() 14 { 15 int i,j,top,k=0; 16 for(j=0; j<n; j++) 17 { 18 for(i=1; i<=n; i++) 19 { 20 if(indegree[i] == 0)///前驱为零即是当前第一名 21 { 22 top = i; 23 break; 24 } 25 } 26 q[k++] = top; 27 indegree[top] = -1; 28 for(i=1; i<=n; i++) 29 { 30 if(ans[top][i]) 31 indegree[i]--;///将前驱中含有当前第一名的前去数量减一 32 } 33 34 35 } 36 for(i=0; i<k-1; i++) 37 printf("%d ",q[i]); 38 printf("%d\n",q[n-1]); 39 } 40 int main() 41 { 42 int i,a,b,m; 43 while(scanf("%d%d",&n,&m)!=EOF) 44 { 45 memset(indegree,0,sizeof(indegree)); 46 memset(ans,0,sizeof(ans)); 47 48 for(i=0; i<m; i++) 49 { 50 scanf("%d%d",&a,&b); 51 if(ans[a][b] == 0) 52 { 53 ans[a][b] = 1; 54 indegree[b]++; 55 } 56 } 57 tuopu(); 58 } 59 }