HDU 1285 确定比赛名次(拓扑排序基础题)

Posted leonard-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 1285 确定比赛名次(拓扑排序基础题)相关的知识,希望对你有一定的参考价值。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1285

题目:

有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.从DAG(有向无环图)中选一个 没有前驱(即入度为0)的顶点并输出。
2.从图中删除该顶点和所有以它为起点的有向边。
3.重复1和2直到当前的DAG为空或当前图中不存在无前驱的顶点为止,后一种情况说明有向图中一定有环。

代码:
 1 #include <queue>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int N=555;
 8 int n,m;
 9 int in[N];
10 bool E[N][N];
11 queue <int> Q;
12 
13 void toposort(){
14     for(int i=1;i<=n;i++){
15         //寻找入度为0的点
16         int j=1;
17         while(in[j]!=0) j++;
18         in[j]--;
19         Q.push(j);
20         //将关联的点的入度减1,即删除与该节点关联的边
21         for(int k=1;k<=n;k++){
22             if(E[j][k]) in[k]--;
23         }
24     }
25 }
26 
27 int main(){
28     int a,b;
29     while(scanf("%d%d",&n,&m)!=EOF){
30         memset(E,0,sizeof(E));
31         memset(in,0,sizeof(in));
32         for(int i=1;i<=m;i++){
33             scanf("%d%d",&a,&b);
34             if(!E[a][b]){
35                 E[a][b]=1;
36                 in[b]++;
37             }
38         }
39         toposort();
40         while(!Q.empty()){
41             if(Q.size()==1) printf("%d\n",Q.front());
42             else printf("%d ",Q.front());
43             Q.pop();
44         }
45     }
46 
47     return 0;
48 }

 

以上是关于HDU 1285 确定比赛名次(拓扑排序基础题)的主要内容,如果未能解决你的问题,请参考以下文章

hdu 1285 确定比赛名次(拓扑排序)

HDU-1285 确定比赛名次(拓扑排序)

HDU[1285]确定比赛名次 拓扑排序

HDU 1285 确定比赛名次(拓扑排序+优先队列)

[ACM] hdu 1285 确定比赛名次 (拓扑排序)

HDU 1285 确定比赛名次(拓扑排序模板)