poj 3687 反向建图 拓扑排序
来源:互联网 发布:mac用什么散热 编辑:程序博客网 时间:2024/06/05 14:36
题目链接http://poj.org/problem?id=3687
题目大意:
拓扑排序
给出一系列的关系,也就是a b两个数,必须保证 贴a标签的球在贴b标签的球的前面,最后排出一个序列,但是要注意的是最后的输出不是这个序列,而是从标签1到标签n所对应的球的重量,如果有多个解,那么就要让前面的标签所对应的重量尽可能的小。。
一开始的思路是用一个优先队列,从而做到从小到大取标签,保证标签号小的在序列的尽可能前面,这样对于比较小的标签,就可以得到比较小的重量了。
交了第一次,妥妥的WA了,因为我输出的整个标签的序列而不是每个标签所对应的球的重量。改完以后交了,还是错,想了好久,看了别人的思路都说这道题要反向建图,在从大往小的取,将大的数尽量放到答案的后面,这样就能够保证小重量的球尽可能的放到了前面。
看到一姐的博客说:每一次让序号大的数尽量往后排,因为从后往前排的时候,决定的位置是越来越重要的。
如果是正向构图的话很容易找出一个反例,
5 4
5 2
2 1
4 3
3 1
如果正向构图那么就是5->2->1 4->3->1 这样的话标签序列就会是(4 3 5 2 1) 所对应的答案就是(5 4 2 1 3)
如果反向构图从大往小的取,并尽可能的将大的放到后面话(也就是将相互之间的方向颠倒一下) 5<-2<-1 4<-3<-1 标签序列就变成(5 2 4 3 1) 答案就是(5 2 4 3 1 )
反向的话才可以找到最优解,,如果正向的话每次取最小,前面的位置是比后面的位置来的重要的,所以并不能保证之前的就是足够小的了,可能有比他更小的情况存在。
反着来,将最大的放到越后面,这样剩下的就是比较小的,也就可以放到前面更加重要的位置中去了。
不过不知道怎么证明这种算法的正确性
这题感觉蛮好的,以后还要再来看看。
代码:
#include <iostream>#include <vector>#include <queue>#include <cstring>#include <cstdio>using namespace std;#define M 50000#define INF 1000000int n,m;int flag;vector<int> G[M];int indegree[M];int judge[300][300];int ans[M];void toposort(){ priority_queue<int> q; //优先队列 从大的往小的取 int num = n; for(int i = 1;i <= n;i++) { if(indegree[i]==0) q.push(i); } while(!q.empty()) { int cur = q.top(); q.pop(); ans[cur] = num; // 将每个标签从后往前放 num--; for(int i = 0;i <= n;i++) { if(judge[cur][i]==1) { indegree[i]--; if(!indegree[i]) q.push(i); } } } if(num>0) flag = 1; //判环}int main(){ int t; cin >> t; while(t--) { flag = 0; cin >> n >> m; memset(indegree,0,sizeof(indegree)); memset(judge,0,sizeof(judge)); for(int i = 0;i < m;i++) { int a,b; cin >> a >> b; if(a==b) flag =1; if(judge[b][a]==1) continue; // 判重即是否之前有一样的 judge[b][a] = 1; //反向构图就是将两个元素的指向相反 if(flag) continue; indegree[a]++; } toposort(); //getchar(); if(flag) cout << -1 << endl; else { for(int i = 1;i < n;i++) cout << ans[i] << " "; cout << ans[n] << endl; } } return 0;}
- poj 3687 拓扑排序 - 反向建图
- poj 3687 拓扑排序 反向建图
- poj 3687 反向建图 拓扑排序
- poj-3687-Labeling Balls-反向建图+拓扑排序
- Labeling Balls poj 3687(拓扑排序反向建图)
- POJ 3687 Labeling Balls (反向拓扑排序)
- POJ:3687 Labeling Balls (反向建图+拓扑排序+优先队列)
- POJ 3687 Labeling Balls(拓扑排序【反向建图+优先队列】)
- Labeling Balls 3687(拓扑排序+反向建图)
- HDU2647(拓扑排序+反向建图)
- poj3687反向建图+拓扑排序
- poj3687 反向建图拓扑排序
- hdu4857 逃生【反向建图+拓扑排序】
- POJ 3687 Labeling Balls (反向拓扑排序)
- POJ 3687 Labeling Balls(拓扑排序+反向思考)
- POJ - 3687Labeling Balls(反向建图 + 反向拓扑)题意坑
- hdu 3687 反向拓扑排序
- POJ 3687 拓扑排序
- volley的详细讲解
- ceph存储 FUSE队列管理浅析
- go -mongodb
- JQuery数字类型验证正则表达式
- UIImage 绘制椭圆
- poj 3687 反向建图 拓扑排序
- [Leetcode Shell] Transpose File
- KB3033889导致 Windows 8、Win8、Windows8.1 任务栏切换时卡死、重启
- 转自高手关于SQL 锁的叙述。。(nolock,rowlock,tablock,xlock,paglock)
- ACM 学习资料
- Liferay Portal 6.2 开发环境搭建
- C# Action<T> 委托
- 自己项目中常用开源库
- 人生苦短,我用Python 学习笔记——第一天