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


Sample Output

    

这是一种比较坑的排序,要求编号小的尽量排在前面,这里平时的是不一样的。

例子来自:https://blog.csdn.net/qq_41713256/article/details/80805338

如果你用优先队列拓扑排序得到的是:3 5 6 4 1 7 8 9 2 0

但是正确答案为 6 4 1 3 9 2 5 7 8 0 这样使得小的(1)尽量在前面。

这题相当于逆向的拓扑排序,因为小的要尽量放前面。

如果正向拓扑的话,优先队列要设置成小的值优先,这样万一出现一个比较小的入度为0的点,就会直接放进queue去 ,这样万一后面还有更小的点的话就出错了。

所以要逆向拓扑,从右往左想,所有特殊条件都没有指明谁要在它后面的点先放(即这个点的出度为0),优先队列设置成大的优先。

思路:逆向拓扑 + 优先队列

1.反向建边,点大的优先级高。
2.用拓扑排序+优先队列,逆向输出序列即可。

 #include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <math.h>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
const int INF=0x3f3f3f3f;
typedef long long LL;
const double eps =1e-;
const int mod=1e9+;
const int maxn=1e5+;
using namespace std; struct edge
{
int to;
int next;
}E[maxn];
int head[maxn];
int tot;
void add(int u,int v)
{
E[tot].to=v;
E[tot].next=head[u];
head[u]=tot++;
} priority_queue<int> qe;
vector<int> ans;
int in[maxn]; void init()
{
tot=;
memset(in,,sizeof(in));
memset(head,-,sizeof(head));
while(!qe.empty()) qe.pop();
ans.clear();
} int main()
{
#ifdef DEBUG
freopen("sample.txt","r",stdin);
#endif int T;
scanf("%d",&T);
while(T--)
{
int n,m;
scanf("%d %d",&n,&m);
init();
for(int i=;i<=m;i++)
{
int u,v;
scanf("%d %d",&u,&v);
add(v,u);
in[u]++;
}
for(int i=;i<=n;i++)
if(in[i]==) qe.push(i);
while(!qe.empty())
{
int u=qe.top(); qe.pop();
ans.push_back(u);
for(int i=head[u];i!=-;i=E[i].next)
{
int v=E[i].to;
in[v]--;
if(in[v]==) qe.push(v);
}
}
for(int i=ans.size()-;i>=;i--)
printf(i==?"%d\n":"%d ",ans[i]);
} return ;
}

-

HDU-4857 逃生(逆向拓扑排序)的更多相关文章

  1. HDU 4857 逃生 【拓扑排序+反向建图+优先队列】

    逃生 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission ...

  2. HDU 4857 逃生(拓扑排序)

    拓扑排序 一.定义 对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若<u,v> ∈ ...

  3. (hdu) 4857 逃生 (拓扑排序+优先队列)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4857 Problem Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄 ...

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

    逃生 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submiss ...

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

    题意:有N个人,M个优先级a,b表示a优先于b.而且每一个人有个编号的优先级.输出顺序. 思路来自:与PKU3687一样 在主要的拓扑排序的基础上又添加了一个要求:编号最小的节点要尽量排在前面:在满足 ...

  6. 题解报告:hdu 2647 Reward(拓扑排序)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2647 Problem Description Dandelion's uncle is a boss ...

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

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4857 逃生 Time Limit: 2000/1000 MS (Java/Others)    Mem ...

  8. hdu 4857 逃生 拓扑排序+PQ,剥层分析

    pid=4857">hdu4857 逃生 题目是求拓扑排序,但不是依照字典序最小输出,而是要使较小的数排在最前面. 一開始的错误思路:给每一个点确定一个优先级(该点所能到达的最小的点) ...

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

    确定比赛名次 Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submis ...

  10. HDU 4857 逃生(反向建边的拓扑排序+贪心思想)

    逃生 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submissi ...

随机推荐

  1. DataReader和DataAdapter的区别

    SqlDataReader是一个向前的指针,本身并不包含数据,调用一次Read()方法它就向前到下一条记录,一个SqlDataReader必须单独占用一个打开的数据库连接. 在使用 SqlDataRe ...

  2. 通过css 居中div的几种常用方法

    1.text-align:center方式 .center{ text-align:center; } center_text{ display:inline-block; width:500px } ...

  3. JS动态判断设备类型为PC或者移动端,然后根据设备加载相应的代码

    这里是通过JS判断设备之后加载相应的网站,如果是移动端加载m开头的网站域名,如果是PC端就加载 www.开头的正式域名 <script> (function () { var url = ...

  4. node - 处理跨域 ( 两行代码解决 )

    1,安装 cors 模块 : npm install cors 2,代码 : var express = require('express') var app = express() var cors ...

  5. epoll源码分析(基于linux-5.1.4)

    API epoll提供给用户进程的接口有如下四个,本文基于linux-5.1.4源码详细分析每个API具体做了啥工作,通过UML时序图理清内核内部的函数调用关系. int epoll_create1( ...

  6. Java笔记--枚举&注解

    1.自定义枚举类的实现,例: class Season{ //1,提供类的属性,声明为rivate final private final String name; private final Str ...

  7. espcms P8.19082801 vulnerability

    author: naiquan chai Net name:Hanamizuki花水木 Through  the vulnerability  we can get the webshell if w ...

  8. 深度学习之常用linux命令总结

    深度学习中常用linux命令总结 1.创建文件夹 mkdir 文件名2.删除文件 rm -d 目录名 #删除一个空目录 rmdir 目录名 #删除一个空目录 rm -r 目录名 #删除一个非空目录 r ...

  9. MyBatis: No MyBatis mapper was found in '[xx.mapper]' package. Please check your configuration

    在应用入口加入@MapperScan("com.IBM.XXXXX.dao")

  10. C++获取文件夹中所有文件

    获取文件夹中的文件,用到过很多次,每次用的时候都要去查下,很烦,所以想自己写下,当然,借鉴了很多其他大佬的博客 主要实现的函数,如下: void getFiles( string path, vect ...