hdu 4857

逃生

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 959    Accepted Submission(s): 284

Problem Description

糟糕的事情发生啦,现在大家都忙着逃命。但是逃命的通道很窄,大家只能排成一行。

现在有n个人,从1标号到n。同时有一些奇怪的约束条件,每个都形如:a必须在b之前。
同时,社会是不平等的,这些人有的穷有的富。1号最富,2号第二富,以此类推。有钱人就贿赂负责人,所以他们有一些好处。

负责人现在可以安排大家排队的顺序,由于收了好处,所以他要让1号尽量靠前,如果此时还有多种情况,就再让2号尽量靠前,如果还有多种情况,就让3号尽量靠前,以此类推。

那么你就要安排大家的顺序。我们保证一定有解。

Input

第一行一个整数T(1 <= T <= 5),表示测试数据的个数。
然后对于每个测试数据,第一行有两个整数n(1 <= n <= 30000)和m(1 <= m <= 100000),分别表示人数和约束的个数。

然后m行,每行两个整数a和b,表示有一个约束a号必须在b号之前。a和b必然不同。

Output

对每个测试数据,输出一行排队的顺序,用空格隔开。

Sample Input

1

5 10

3 5

1 4

2 5

1 2

3 4

1 4

2 3

1 5

3 5

1 2

Sample Output

1 2 3 4 5

拓扑排序,并且字典序最小

可以用优先队列+反拓扑排序+倒序输出

 1 #include<string>
 2 #include<cstdio>
 3 #include<iostream>
 4 #include<vector>
 5 #include<queue>
 6 #include<stack>
 7 #include<algorithm>
 8 #include<cstring>
 9 #include<stdlib.h>
10 #include<string>
11 #include<cmath>
12 using namespace std;
13 #define pb push_back
14 vector<int >p[30010];
15 int in[30010],n,m,deep[10010],num[10010];
16 char dp[2010][2010];
17 void init(){
18     memset(in,0,sizeof(in));
19     memset(deep,0,sizeof(deep));
20     memset(num,0,sizeof(num));
21     for(int i=0;i<=n;i++) p[i].clear();
22 }
23 int tuopu(){
24     priority_queue<int >ak_47;
25     stack<int >ko;
26     int cnt=0;
27     for(int i=1;i<=n;i++)
28     if(in[i]==0) ak_47.push(i);
29     while(!ak_47.empty()){
30         int pos=ak_47.top();
31         ko.push(pos);
32         ak_47.pop();
33         for(int i=0;i<p[pos].size();i++){
34             int to=p[pos][i];
35             if((--in[to])==0) ak_47.push(to);
36         }
37
38     }
39     while(!ko.empty()){
40         if(cnt) printf(" ");
41         cnt=1;
42         printf("%d",ko.top());
43         ko.pop();
44     }
45     printf("\n");
46 }
47 int main(){
48     int cas=0,t;
49     cin>>t;
50     while(t--){
51         cin>>n>>m;
52         init();
53         for(int i=1;i<=m;i++){
54            int a,b;scanf("%d%d",&a,&b);
55            in[a]++,p[b].pb(a);
56         }
57         tuopu();
58     }
59 }

hdu 4857,布布扣,bubuko.com

时间: 2024-08-14 08:18:26

hdu 4857的相关文章

hdu 4857 逆拓扑+大根堆(priority_queue)

题意:排序输出:在先满足定约束条件下(如 3必需在1前面,7必需在4前面),在满足:1尽量前,其次考虑2,依次.....(即有次约束). 开始的时候,只用拓扑,然后每次在都可以选的时候,优先考虑小的,其实没什么简单,如 图(3-->1,2)这样输出是2.3.1,正确应该是 3 1 2,因为 1要尽量前(都满足第一约束). 参考他人思路结合自己理解:因为这样的弊端就是没有考虑这种情况:图中:若我的"子孙"中,有的比你次优先,虽然现在我们都可以输出,但是要考虑我的子代,若我的子代有次

HDU 4857 Couple doubi(找循环节)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4861 解题报告:桌子上有k个球 ,第i个球的价值wi = 1^i+2^i+...+(p-1)^i (mod p),现在两个人轮流取,如果第一个取的人最后得到的价值总和最大,输出YES,否则 输出NO . k和p的范围都很大,如果都算出来那是不可能的,所以一定是有规律的,所以我把前面的几个打表看了一下,果然有规律,第1.2.3.......(p-2),(p-1)个球的价值分别是: 0,0,0.....

HDU 4857 topological_sort

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

hdu 4857 逃生 (拓扑排序+保证最小在前面)

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

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

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

HDU 4857 拓扑排序 优先队列

n个数,已经有大小关系,现给m个约束,规定a在b之前,剩下的数要尽可能往前移.输出序列 大小关系显然使用拓扑结构,关键在于n个数本身就有大小关系,那么考虑反向建图,优先选择值最大的入度为零的点,这样得到的序列就是从大到小的,最后倒序输出就行了. 写这题的时候头好痛阿肚子好痛阿,再也不想熬夜了,一点效率都没有. /** @Date : 2017-09-29 19:29:12 * @FileName: HDU 4857 拓扑排序 + 优先队列.cpp * @Platform: Windows * @

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

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4857 解题报告:有n个点,有m个条件限制,限制是像这样的,输入a  b,表示a必须排在b的前面,如果不能确定两个数谁排在前面则尽量把小的排在前面. 首先把出度为0的点加入到优先队列中,然后每次用优先队列中弹出的点去更新其它点的出度,更新的同时如果又有其它点的出度为0的话又加到优先队列中, 最后按照从优先队列中出队的反序输出就可以了.我还是不懂为什么按照入度为0然后加入到优先队列然后正序输出这样为什么

hdu 4857 逃生 拓扑排序+优先队列,逆向处理

hdu4857 逃生 题目是求拓扑排序,但不是按照字典序最小输出,而是要使较小的数排在最前面. 一开始的错误思路:给每个点确定一个优先级(该点所能到达的最小的点),然后用拓扑排序+优先对列正向处理,正向输出.这是错误的,如下样例: 1 5 4 5 2 4 3 2 1 3 1 正确的解法:是反向建边,点大的优先级高,用拓扑排序+优先队列,逆向输出序列即可. 根据每对限制,可确定拓扑序列,但此时的拓扑序列可能有多个(没有之间关系的点的顺序不定).本题要求较小的点排到前面,则可确定序列. (1)如果点

BestCoder Round #1 1001 &amp;&amp; 1002 hdu 4857 4858

hdu 4857 逃生 第一题是拓扑排序,不是按照字典序最小输出,而是要使较小的数排在最前面..赛后弄了好久,才比较明白,我一直以为 反向建图,i从1到n,开始深搜dfs( i ),对i点的边,由小到大继续搜一下,同时标记搜过的数,搜过之后就不再搜,搜到底之后ans[cnt++] = u;这样顺序输出就是答案,后来经过超哥指点,才明白深搜贪心是错的.只有 反向建图,用优先队列把较大的数尽量排在前面,然后反序输出才是正解.. 1 #include<iostream> 2 #include<