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

解题报告:

有n支球队参加比赛,现在裁判手中有每场比赛的胜负信息,要求利用这些信息为所有球队排名,如果两支球队不能确定胜负的,要求把球队编号小的放前面,输入首先有一个n,一个m,然后有m行,每行输入一对数字,如输入x y表示编号为x的球队赢了编号为y 的球队。

感觉这题优点BT,本来题目不难,就是一道拓扑排序的裸题,但是最大的问题就是重边,一开始没注意,WA了n次,拓扑排序的原理就是每次把入度为0的点输出,然后把以这个点为出度的边删掉,删掉边其实就是把以这个点为始点的边上的终点的入度减掉一,然后循环这两步就可以了。附上终极测试数据加上AC代码:

6 11
5 3
5 3
5 1
5 4
5 2
3 1
3 2
6 4
6 2
4 2
4 2 

 1 #include<cstdio>
 2 #include<cstring>
 3 const int MAX = 505;
 4 int map[MAX][MAX],visit[MAX],du[MAX];
 5 
 6 int main() {
 7     int n,m,x,y;
 8     while(scanf("%d%d",&n,&m)!=EOF) {
 9         memset(du,0,sizeof(du));
10         memset(map,0,sizeof(map));
11         memset(visit,0,sizeof(visit));
12         while(m--) {
13             scanf("%d%d",&x,&y);
14             if(!map[x][y])     //防止重边 
15             du[y]++;
16             map[x][y] = 1;     //标记x<y 
17         }
18         int flag = 1;        //标记第一次输出 
19         for(int i = 1;i<=n;++i)
20         if((!visit[i])&&(!du[i])) {
21             printf(flag? "%d":" %d",i);
22             visit[i] = 1;
23             flag = 0;
24             for(int j = 1;j<=n;++j)
25             if(map[i][j])
26             du[j]--;
27             i = 0;           //输出一个后,从头开始判断,注意不能是1 
28         }
29         puts("");
30     }
31     return 0;
32 }
View Code
原文地址:https://www.cnblogs.com/xiaxiaosheng/p/3198019.html