九度OJ 1449:确定比赛名次
- 题目描述:
-
有N个比赛队(1<=N<=500),编号依次为1,2,3,。。。。,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1赢P2,用P1,P2表示,排名时P1在P2之前。现在请你编程序确定排名。
- 输入:
-
输入有若干组,每组中的第一行为二个数N(1<=N<=500),M;其中N表示队伍的个数,M表示接着有M行的输入数据。接下来的M行数据中,每行也有两个整数P1,P2表示即P1队赢了P2队。
- 输出:
-
给出一个符合要求的排名。输出时队伍号之间有空格,最后一名后面没有空格。
其他说明:符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前;输入数据保证是正确的,即输入数据确保一定能有一个符合要求的排名。
- 样例输入:
-
4 3 1 2 2 3 4 3
- 样例输出:
-
1 2 4 3
#include <cstdio> #include <vector> #include <queue> #include <algorithm> #define N 501 using namespace std; struct edge{ int t; }; int main() { vector<edge> graph[N]; queue<int> Q; int n,m; bool mark[N]; int du[N]; while(scanf("%d%d",&n,&m) != EOF){ if(n == 0 && m == 0)break; for(int i = 1;i <= n;i++){ graph[i].clear(); du[i] = 0; mark[i] = false; } for(int i = 0;i < m;i++){ int from,to; scanf("%d%d",&from,&to); edge tmp; tmp.t = to; graph[from].push_back(tmp); du[to]++; } while(!Q.empty())Q.pop(); for(int i = 1;i <= n;i++) if(du[i] == 0){ Q.push(i); break; } bool first = true; while(!Q.empty()){ int x = Q.front(); Q.pop(); mark[x] = true; if(first){ printf("%d",x); first = false; }else printf(" %d",x); for(int j = 0;j < graph[x].size();j++){ int to = graph[x][j].t; du[to]--; } for(int i = 1;i <= n;i++) if(du[i] == 0 && mark[i] == false){ Q.push(i); break; } } printf("\n"); } return 0; }