HDU - 4857 逃生(反向建图 + 拓扑排序)
2015-08-19 16:26
513 查看
题意:虽然是中文,但是有必要说一说,一开始我以为是如果存在拓扑序不唯一的情况时输出字典序最小的拓扑序列,然后就哇了,后来明白了,每个人都有一个优先级(1-n递减),尽可能的把优先级高的人,往前安排
比如数据
3 1
3 1
那么输出的应该是 3 1 2而不是字典序最小的2 3 1.
所以反向建图,在拓扑排序就好了,(不用优先队列会超时)
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
比如数据
3 1
3 1
那么输出的应该是 3 1 2而不是字典序最小的2 3 1.
所以反向建图,在拓扑排序就好了,(不用优先队列会超时)
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
#include<algorithm> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<list> #include<iostream> #include<map> #include<queue> #include<set> #include<stack> #include<vector> using namespace std; int buf[10]; //整型变量快速输入输出函数 inline int readint() { char c = getchar(); while(!isdigit(c)) c = getchar(); int x = 0; while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); } return x; } inline void writeint(int i) { int p = 0; if(i == 0) p++; else while(i) { buf[p++] = i % 10; i /= 10; } for(int j = p - 1 ; j >= 0 ; --j) putchar('0' + buf[j]); } ////////////////////////////////////////////////////////////////////// #define MAX_N 30005 #define MAX_M 100005 const int INF = 0x3f3f3f3f; vector<int> v; priority_queue<int, vector<int>, less<int> > pq; int n, m; int que[MAX_N]; int head[MAX_N]; int top; struct node { int to, next; } edge[MAX_M]; int indegree[MAX_N]; void init() { memset(head, -1, sizeof(head)); memset(indegree, 0, sizeof(indegree)); v.clear(); while(!pq.empty()) pq.pop(); top = 0; } void add_edge(int u, int v) { edge[top].to = v; edge[top].next = head[u]; head[u] = top++; } void topo_sort() { for(int i = 1 ; i <= n ; i++) { if(indegree[i] == 0) { pq.push(i); } } while(!pq.empty()) { int p = pq.top(); pq.pop(); v.push_back(p); for(int k = head[p] ; k != -1; k= edge[k].next) { indegree[edge[k].to]--; if(indegree[edge[k].to] == 0) { pq.push(edge[k].to); } } } for(int i = n -1 ; i >= 0 ; i--) { printf("%d%c", v[i], i == 0 ? '\n' : ' '); } } int main() { int t; int u, v; t = readint(); while(t--) { init(); n = readint(); m = readint(); for(int i = 0 ; i < m ; i++) { u = readint(); v = readint(); add_edge(v, u); indegree[u]++; } topo_sort(); } return 0; }
相关文章推荐
- shell的追踪与调试选项
- 二分图-最大匹配,最小路径覆盖,最小点覆盖(KM算法)
- SpringAOP拦截Controller,Service实现日志管理(自定义注解的方式)
- EL字符串表达式和常用功能用途拦截
- comparable与comparator比较
- fckeditor的用法
- Java jvisualvm简要说明
- 桌面支持--PLM软件必须右键用管理员账号打开
- centos7 lamp环境配置及多域名设置
- 网页浮动图片的设置
- IE获取文件目录下的文件列表及ActiveXObject IE设置
- Perforce初体验
- 桌面支持--Office2013没有Office Picture Manage怎么安装
- Objective-C中不同方式实现锁(一)
- js 判断文件是否存在
- 单线程代码事例
- 多校第九场Too Simple题解
- 13. CSS 链接
- 理解HotSpot的CMS GC
- 使用文件重定向