hdu 1285 确定比赛名次(拓扑排序)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 1285 确定比赛名次(拓扑排序)相关的知识,希望对你有一定的参考价值。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1285思路:a队赢了b队,代表一个从a到b的有向边,对这个图求拓扑排序,如果有多个答案,按照数字升序输出。寻找拓扑序列,看代码注释。
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
代码:
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; const int N = 600; int mp[N][N]; int edge[N]; int flag[N]; struct line { int exist; //代表当前边是否存在 int u; //边的起始点 int v; //边的终点 }; struct line l[N * N]; void debug(int *num, int n) { for (int i = 1; i <= n; i++) printf("%d%c", num[i], i == n ? ‘\n‘ : ‘ ‘); } int main() { int n, m; while (scanf("%d%d", &n, &m) != EOF) //n代表点的数目,m代表边的数目。 { for (int i = 0; i < m; i++) //边的输入 { scanf("%d%d", &l[i].u, &l[i].v); l[i].exist = 1; } for (int i = 0; i < n; i++) //循环n次寻找拓扑序列 { for (int j = 1; j <= n; j++) //flag[i]代表第i个点是否为入度为0的点 flag[j] = 1; for (int j = 0; j < m; j++) //如果有边的终点是j,那么flag[j]置零。 { if(l[j].exist == 1) flag[l[j].v] = 0; } for (int j = 0; j < i; j++) //已经加入拓扑序列的点也置零。 flag[edge[j]] = 0; //debug(flag, n); for (int j = 1; j <= n; j++) //从终点里选取一个数字最小的点。 { if (flag[j] == 1) { edge[i] = j; break; } } for (int j = 0; j < m; j++) //对于加入拓扑序列的这个点,删除其所在的边。 { if(l[j].u == edge[i]) l[j].exist = 0; } } for (int i = 0; i < n; i++) //拓扑序列已找到,输出即可。 printf("%d%c", edge[i], i == n - 1 ? ‘\n‘ : ‘ ‘); } return 0; }
以上是关于hdu 1285 确定比赛名次(拓扑排序)的主要内容,如果未能解决你的问题,请参考以下文章