解题报告:
有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 }