poj3687Labeling Balls【反向拓扑排序 模板】
2016-02-03 15:55
405 查看
Labeling Balls
Description
Windy has N balls of distinct weights from 1 unit to N units. Now he tries to label them with 1 to
N in such a way that:
No two balls share the same label.
The labeling satisfies several constrains like "The ball labeled with a is lighter than the one labeled with
b".
Can you help windy to find a solution?
Input
The first line of input is the number of test case. The first line of each test case contains two integers,
N (1 ≤ N ≤ 200) and M (0 ≤ M ≤ 40,000). The next
M line each contain two integers a and b indicating the ball labeled with
a must be lighter than the one labeled with b. (1 ≤ a, b ≤
N) There is a blank line before each test case.
Output
For each test case output on a single line the balls' weights from label 1 to label
N. If several solutions exist, you should output the one with the smallest weight for label 1, then with the smallest weight for label 2, then with the smallest weight for label 3 and so on... If no solution exists, output -1 instead.
Sample Input
Sample Output
折腾了将近两个小时总算在discuess的只言片语中知道自己错在哪里了,怎么说也是没参考别人代码A的,但是思维严谨性啊……自己写测试数据!自己好好读题!
1.题中有一句特别坑爹的话:For each test case output on a single line the balls' weights from label 1 to labelN. 输出的是这个数字所在的位置 ,不是这个位置上的数字
2.反向输出!这个写几组数据就能看出来吧。但是为什么呢?因为如果只是限制优先级,小的数先输出,有可能得不到正解,反向输出,大的放到后面就解决了这个问题
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 12994 | Accepted: 3748 |
Windy has N balls of distinct weights from 1 unit to N units. Now he tries to label them with 1 to
N in such a way that:
No two balls share the same label.
The labeling satisfies several constrains like "The ball labeled with a is lighter than the one labeled with
b".
Can you help windy to find a solution?
Input
The first line of input is the number of test case. The first line of each test case contains two integers,
N (1 ≤ N ≤ 200) and M (0 ≤ M ≤ 40,000). The next
M line each contain two integers a and b indicating the ball labeled with
a must be lighter than the one labeled with b. (1 ≤ a, b ≤
N) There is a blank line before each test case.
Output
For each test case output on a single line the balls' weights from label 1 to label
N. If several solutions exist, you should output the one with the smallest weight for label 1, then with the smallest weight for label 2, then with the smallest weight for label 3 and so on... If no solution exists, output -1 instead.
Sample Input
5 4 0 4 1 1 1 4 2 1 2 2 1 4 1 2 1 4 1 3 2
Sample Output
1 2 3 4 -1 -1 2 1 3 4 1 3 2 4
折腾了将近两个小时总算在discuess的只言片语中知道自己错在哪里了,怎么说也是没参考别人代码A的,但是思维严谨性啊……自己写测试数据!自己好好读题!
1.题中有一句特别坑爹的话:For each test case output on a single line the balls' weights from label 1 to labelN. 输出的是这个数字所在的位置 ,不是这个位置上的数字
2.反向输出!这个写几组数据就能看出来吧。但是为什么呢?因为如果只是限制优先级,小的数先输出,有可能得不到正解,反向输出,大的放到后面就解决了这个问题
/**************** poj3687 2016.2.3 916K 79MS G++ 1939B ****************/ #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <queue> #include<vector> using namespace std; const int maxn=300; int tmp[400]; bool mark[205][205]; int head[maxn],ip,indegree[maxn]; int t,n,m,seq[maxn]; struct cmp1{ bool operator ()(int &a,int &b){ return a<b;//最大值优先 } }; struct note { int v,next; } edge[maxn*maxn]; void init() { memset(head,-1,sizeof(head)); ip=0; memset(indegree,0,sizeof(indegree)); memset(mark,0,sizeof(mark)); } void addedge(int u,int v) { edge[ip].v=v,edge[ip].next=head[u],head[u]=ip++; } int topo()///拓扑,可做模板 { priority_queue<int,vector<int>,cmp1>que1; int indeg[maxn]; for(int i=1; i<=n; i++) { indeg[i]=indegree[i]; if(indeg[i]==0) que1.push(i); } int k=n; bool res=false; while(!que1.empty()) { if(que1.size()!=1)res=true; int u=que1.top(); que1.pop(); seq[k--]=u; for(int i=head[u]; i!=-1; i=edge[i].next) { int v=edge[i].v; indeg[v]--; if(indeg[v]==0) que1.push(v); } } if(k>0)return -1;///存在有向环,总之不能进行拓扑排序 if(res)return 0;///可以进行拓扑排序,并且只有唯一一种方式,seq数组即是排序完好的序列 return 1;///可以进行拓扑排序,有多种情况,seq数组是其中一种序列 } int main() { 、、freopen("cin.txt","r",stdin); scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); init(); while(m--) { int a,b; scanf("%d%d",&a,&b); if(mark[a][b]) continue; addedge(b,a); indegree[a]++; mark[a][b]=1; } if(topo()==-1) printf("-1\n"); else { for(int i=1;i<=n;i++) tmp[seq[i]]=i; for(int i=1;i<n;i++) printf("%d ",tmp[i]); printf("%d\n",tmp ); } } return 0; }
相关文章推荐
- select、poll、epoll之间的区别总结[整理]
- 会话跟踪技术--cookie和session 小结
- STS上配置maven 更改maven仓库位置
- 解决Eclipse和myeclipse在进行 html,jsp等 页面编辑时,自动格式化变丑的问题
- CountDownLatch, CyclicBarrier, Phaser 总结
- 使用 Jmeter 做 Web 接口测试
- HDU5437 结构体排序和优先队列
- 分布式一致性算法:Raft算法
- POJ 1260 Pearls(DP)
- BZOJ 1084: [SCOI2005]最大子矩阵 DP
- Window.open()方法参数详解
- JQuery Autocomplete实战
- 使用ASM操作Java字节码,实现AOP原理
- 左右滑动与上下滑动的冲突
- <重拾C++>const
- osg实现透明效果 正解
- 模板引擎FreeMarker【整理1】
- 贝叶斯法则与先验概率,后验概率
- Tip_高维寻址
- 创建jsp模板