逃生(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("\n");
50     }
51     return 0;
52 }

原文地址:https://www.cnblogs.com/Dillonh/p/9004651.html

时间: 2024-10-27 03:07:50

逃生(HDU4857 + 反向拓扑排序)的相关文章

HDU 4857 逃生 (反向拓扑排序 &amp; 容器实现)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4857 逃生 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4505    Accepted Submission(s): 1282 Problem Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排

HDU 4857 逃生(反向拓扑排序+优先队列)

( ̄▽ ̄)" //这题对序号输出有要求,较小的序号优先输出,所以用到优先队列 //优先队列是优先弹出值最大的,所以最后要反向输出结果,才是正确的output #include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> #include<string> #include<cstdlib> #inc

hdu 4857 逃生【反向拓扑排序】

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4857 题意:中文不解释 解法: input: 1 3 1 3 1 answer: 3 1 2 而不是 2 3 1 所以逆向建边 拓扑 代码: #include<stdio.h> #include<iostream> #include<math.h> #include<stdlib.h> #include<ctype.h> #include<a

HDU 4857 (反向拓扑排序 + 优先队列)

题意:有N个人,M个优先级a,b表示a优先于b,并且每个人有个编号的优先级,输出顺序. 思路来自:与PKU3687一样 在基本的拓扑排序的基础上又增加了一个要求:编号最小的节点要尽量排在前面:在满足上一个条件的基础上,编号第二小的节点要尽量排在前面:在满足前两个条件的基础上,编号第三小的节点要尽量排在前面--依此类推.(注意,这和字典序是两回事,不可以混淆.) 如图 1 所示,满足要求的拓扑序应该是:6 4 1 3 9 2 5 7 8 0. 图 1 一个拓扑排序的例子 一般来说,在一个有向无环图

反向拓扑排序

对于初始没有进行编号,且要求数字小的尽可能在前面 需要进行反向拓扑排序 真的看不懂 反正需要进行 邻接表优化 传送门 传送门 #include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; const int N = 3e4+5; int n,m,cnt; bool mp[N][N]; int du[N],head[N]; int a

HDU4857 逃生【逆拓扑排序】

逃生 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1450    Accepted Submission(s): 448 Problem Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前. 同时,社会

正向与反向拓扑排序的区别(hdu 1285 确定比赛名次和hdu 4857 逃生)

确定比赛名次 Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submission(s) : 16   Accepted Submission(s) : 9 Problem Description 有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比

【HDOJ4857】【反向拓扑排序】

http://acm.hdu.edu.cn/showproblem.php?pid=4857 逃生 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6665    Accepted Submission(s): 1950 Problem Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行.现

POJ3687 反向拓扑排序

Labeling Balls Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16032   Accepted: 4713 Description Windy has N balls of distinct weights from 1 unit to N units. Now he tries to label them with 1 to N in such a way that: No two balls share