题目链接: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
糟糕的事情发生啦,现在大家都忙着逃命。但是逃命的通道很窄,大家只能排成一行。

现在有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
 
题意:n个结点,m个拓扑关系(a,b)表示a必须排在b前面,在满足m个拓扑关系关系的前提下使得小的结点尽可能的排在前面。
也就是说我们现在要从1号结点开始考虑,如果要排1号结点,根据拓扑关系,首先必须排哪些结点,如果排好了1号结点,则继续考虑2号结点 ,3号结点。。 
我们先看两个例子: 
存在拓扑关系: 
5 -> 3 -> 1 
6 -> 4 -> 2 
直接拓扑排序的结果是 5 3 1 6 4 2,结果是正确的(1号尽可能的在前面了) ,看起来好像直接拓扑排序就可以了,
但是为什么提交后却wa了呢,别急,我们再看一个例子: 
6 -> 3 -> 1 
5 -> 4 -> 2 
直接拓扑排序的结果是:5 4 2 6 3 1 ,结果是错误的,因为我们可以把1号安排到更前面的位置 即:6 3 1 5 4 2(正确答案)。 
看到这里应该就知道为什么直接拓扑排序不行了吧,我们分析一下为什么会出现这样的状况,对于多条弧或者边,
我们是先删除弧尾结点比较小的结点即(5号结点比6号结点小,先删除以该点为尾的弧),而这也正是问题所在,
我们希望的是优先删除弧头比较小的弧的(1号结点比2号结点小,因优先删除以1号为头的弧)。 
好了,问题找到了,现在我们在来想如何解决问题,我们可以尝试一下逆向思维,即我们先考虑哪些点应该靠后释放,
这样的话我们就可以把拓扑关系反过来(即弧头和弧尾调换),然后做拓扑排序,
然后我们可以根据原来的弧头(现在变成弧尾)的大小来释放结点,由于现在的问题变成哪些最后释放,
那么就应该优先考虑弧尾(原来的弧头)比较大的,可以通过优先队列来解决。
 
 #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
#define maxx 30010
vector <int > vec[maxx];
priority_queue <int > q; //优先队列
int num[maxx],in[maxx];
int main ()
{
int t,u,v,m,n,i,j;
scanf("%d",&t);
while (t --)
{
scanf("%d%d",&n,&m);
for (i = ; i <= n; i ++) //清空容器内的数据
vec[i].clear();
memset(in,,sizeof(in)); //入度初始化为0 for (i = ; i < m; i ++)
{
scanf("%d%d",&u,&v);
in[u] ++;
vec[v].push_back(u);
}
for (i = ; i <= n; i ++) //将入度为0的点加入优先队列
if (in[i]==) q.push(i); j = ;
while(!q.empty())
{
int k = q.top();
q.pop();
num[j ++] = k;
int len = vec[k].size();
for (i = ; i < len; i ++) // 删除与度数为0的节点相关联的边
{
int l = vec[k][i];
in[l] --;
if (in[l]==)
q.push(l);
}
}
for (i = j-; i >= ; i --)
{
if (i==)
printf("%d",num[i]);
else
printf("%d ",num[i]);
}
printf("\n");
}
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 (反向拓扑排序 + 优先队列)

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

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

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

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

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

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

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

  6. HDU-4857 逃生(反向拓扑排序 + 逆向输出)

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

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

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4857 题面是中文题面,就不解释题意了,自己点击链接去看下啦~这题排序有两个条件,一个是按给定的那个序列 ...

  8. CF-825E Minimal Labels 反向拓扑排序

    http://codeforces.com/contest/825/problem/E 一道裸的拓扑排序题.为什么需要反向拓扑排序呢?因为一条大下标指向小下标的边可能会导致小下标更晚分配到号码,导致字 ...

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

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

随机推荐

  1. Fibonacci(斐波那契)非递归实现。容易看懂

    #include<iostream>using namespace std;int main(){ int n; cout<<"please input a n\n& ...

  2. thunkify 模块

    function thunkify(fn){ assert('function' == typeof fn, 'function required'); return function(){ var ...

  3. Highcharts使用

    Highcharts图表控件是使用比较广泛的图表控件.本文将介绍如何配置Highcharts和动态生成Highcharts图表.可参考Highcharts官网:http://www.highchart ...

  4. Java JDK 环境变量配置

    1:环境 JDK1.7.0 WIN7 2:安装JDK 选择安装目录 安装过程中会出现两次 安装提示 .第一次是安装 jdk ,第二次是安装 jre .建议两个都安装在同一个java文件夹中的不同文件夹 ...

  5. ssh 无密码登陆

    ssh -i littlesuccess-aws.pem root@172.31.36.91 "cat >> ~/.ssh/authorized_keys" < ...

  6. <转载>SQL查询数据库各表所占空间

    IF OBJECT_ID('tempdb..#TB_TEMP_SPACE') IS NOT NULL DROP TABLE #TB_TEMP_SPACE GO CREATE TABLE #TB_TEM ...

  7. C++重载流运算符,将存储结构体的vector直接写入文件

    我们知道,当vector很大的时候,如果使用循环的方式将其中的元素写入文件将非常费时,因此有没有办法将vector一次性写入文件呢? 采用流运算符重载的方法可以做到,不仅基本类型的vector可以一次 ...

  8. Python错误和异常学习

    一:错误解释 1.语法错误:代码不符合解释器或者编译器语法 2.逻辑错误:不完整或者不合法输入或者计算出现问题 代码运行前的语法或者逻辑错误,语法错误在执行前修改,逻辑错误无法修改 二:异常 执行过程 ...

  9. AngularJs的UI组件ui-Bootstrap分享(九)——Alert

    alert指令会在页面上显示一条提示消息,效果是这样: 代码为: <!DOCTYPE html> <html ng-app="ui.bootstrap.demo" ...

  10. 2013年最棒的4个PHP框架

    PHP 框架可以帮你编写简洁可重用的代码,遵循 MVC 模式,确保应用逻辑和展现分离.有很多很多的框架各有千秋,有的性能好,有的文档全,还有的提供大量的内建功能等等. 这里我们罗列的 2013 年最好 ...