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

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
 

 
拓扑排序+优先队列维护字典序
 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 500 + 10;
 4 int topo[maxn], in[maxn], n, m, t;
 5 vector<int> G[maxn];
 6 priority_queue<int, vector<int>, greater<int> > q;
 7 
 8 void toposort() {
 9     while(!q.empty()) {
10         int u = q.top(); q.pop();
11         topo[++t] = u;
12         int len = G[u].size();
13         for (int i = 0; i < len; ++i) {
14             int v = G[u][i];
15             --in[v];
16             if (!in[v]) q.push(v);
17         }
18     }
19 }
20 
21 int main() {
22     int a, b;
23     while(cin>>n>>m) {
24         memset(in, 0, sizeof(in));
25         while(m--) {
26             cin>>a>>b;
27             G[a].push_back(b);
28             ++in[b];
29         }
30         for (int i = 1; i <= n; ++i)
31             if (!in[i]) q.push(i);
32         t = 0;
33         toposort();
34         for (int i = 1; i <= n; ++i)
35             if (i == 1) cout<<topo[i];
36             else cout<<" "<<topo[i];
37         cout<<endl;
38         for (int i = 1; i <= n; ++i) G[i].clear();
39         while(!q.empty()) q.pop();
40     }
41 
42     return 0;
43 }
原文地址:https://www.cnblogs.com/robin1998/p/6456064.html