hdu1285 确定比赛名次【拓扑排序】

题目链接

                                              确定比赛名次

                                        Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
                                                              Total Submission(s): 31474    Accepted Submission(s): 12400

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 <cstdio>
 2 #include <cstring>
 3 
 4 #define rep(i,s,t) for(int i=s;i<=t;i++)
 5 const int N =505;
 6 int g[N][N],ans[N],ind[N];
 7 int n,m;
 8 
 9 void topolopy(){
10     int top,num=0;
11     rep(k,1,n){   //因为每个点都会作为top点操作一次,所以循环n次 
12         rep(i,1,n) if(!ind[i]){    //找到入读度为0的点 
13             top=i;break;
14         }
15         ans[++num]=top;if(num==n)break;  //储存该点 
16         ind[top]=-1;   //将当前入度为0的点入度置为-1,防止重复使用 
17         rep(i,1,n) if(g[top][i]==1){
18             ind[i]--;   //将点的入度-- 
19         }
20     } 
21     rep(i,1,num)i==num?printf("%d
",ans[i]):printf("%d ",ans[i]);
22 }
23 
24 int main(){
25     while(~scanf("%d%d",&n,&m)){
26         memset(g,0,sizeof(g));
27         memset(ind,0,sizeof(ind));
28         rep(i,1,m){
29             int u,v;scanf("%d%d",&u,&v);
30             if(!g[u][v]){    //防止重复  
31                 g[u][v]=1;  //标记u--->v的关系 
32                 ind[v]++;   //v入度+1 
33             }
34         }    
35         topolopy();
36     }
37 }
 
 
2018-04-01


作者:is_ok
出处:http://www.cnblogs.com/00isok/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

原文地址:https://www.cnblogs.com/00isok/p/8687862.html