逃生(HDU4857 + 反向拓扑排序)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4857

题面是中文题面,就不解释题意了,自己点击链接去看下啦~这题排序有两个条件,一个是按给定的那个序列(即输入的u,v,优先级最高),一个是序号从小到大(优先级次之)。正向的话由于这两个条件不好维护,所以就想着用反向拓扑排序来实现。首先记录每个节点的出度,然后用优先队列来维护顺序(使用默认的从大到小排序),最后反向输出即可。

代码实现如下:

 1 #include <queue>
 2 #include <cstdio>
 3 #include <vector>
 4 #include <cstring>
 5 using namespace std;
 6 
 7 const int maxn = 3e4 + 7;
 8 int t, n, m, u, v, rk;
 9 int InDeg[maxn], Rank[maxn];
10 vector<int> G[maxn];
11 
12 void topsort() {
13     priority_queue<int> q;
14     for(int i = 1; i <= n; i++) {
15         if(InDeg[i] == 0) q.push(i);
16     }
17     int x;
18     while(!q.empty()) {
19         x = q.top(), q.pop();
20         Rank[rk++] = x;
21         int t = G[x].size();
22         for(int i = 0; i < t; i++) {
23             if(--InDeg[G[x][i]] == 0) q.push(G[x][i]);
24         }
25     }
26 }
27 
28 int main() {
29     scanf("%d", &t);
30     while(t--) {
31         scanf("%d%d", &n, &m);
32         for(int i = 0; i <= n; i++) {
33             G[i].clear();
34         }
35         memset(InDeg, 0, sizeof(InDeg));
36         for(int  i = 0; i < m; i++) {
37             scanf("%d%d", &u, &v);
38             G[v].push_back(u);
39             InDeg[u]++;
40         }
41         rk = 0;
42         topsort();
43         for(int i = n - 1; i >= 0; i--) {
44             if(i != (n - 1)) {
45                 printf(" ");
46             }
47             printf("%d", Rank[i]);
48         }
49         printf("
");
50     }
51     return 0;
52 }
原文地址:https://www.cnblogs.com/Dillonh/p/9004651.html