POJ 3687 Labeling Balls
2017-03-31 17:06
302 查看
题意:
有n个小球,权重分别为1~n。现在要为这些小球贴上1~n的标签,规则是标签1所对应的小球的权重应尽量小,其次是标签2...接下来会有m个要求,就是标签a所贴小球的权重必须小于标签b所贴小球的权重。
思路:
拓扑排序。
首先我考虑的是正向的拓扑排序,建好图后每次选择度数为0的最小的顶点,为它贴上当前权重最小的小球。但是这样做有缺陷,举个例子来说:
53 14 42 35 正确答案应该是输出13425,但是如果按照我的做法去做的话,输出的是14235。因为2在4后面,先处理了3,这样导致了标签2所贴球的权重较大,最优的是先处理4,这样2就能有较小值。 于是考虑用反向拓扑来做,每次将小的那端的度数+1,每次选择度数为0的最大的顶点,为它贴上当前权重最大的小球。这样就保证了大标签贴在了权重大的球上。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> usingnamespacestd; constintmaxn=200+5; intn,m; intg[maxn][maxn]; intindegree[maxn]; intans[maxn]; inttuopu() { intcnt=n; for(inti=1;i<=n;i++) { intnum=0,loc; for(intj=1;j<=n;j++) { if(indegree[j]==0) { num++; loc=j; } } if(num==0)return-1; ans[loc]=cnt--; indegree[loc]=-1; for(intj=1;j<=n;j++) if(g[loc][j])indegree[j]--; } return1; } intmain() { //freopen("D:\\txt.txt","r",stdin); intT; intx,y; scanf("%d",&T); while(T--) { memset(g,0,sizeof(g)); memset(indegree,0,sizeof(indegree)); memset(ans,0,sizeof(ans)); boolflag=true; scanf("%d%d",&n,&m); while(m--) { scanf("%d%d",&x,&y); if(x==y)flag=false; //反向拓扑 if(!g[y][x])//这里需要注意一下重边的问题 { g[y][x]=1; indegree[x]++; } } if(flag) { intp=tuopu(); if(p==-1)printf("-1\n"); else { for(inti=1;i<n;i++) cout<<ans[i]<<""; cout<<ans <<endl; } } elseprintf("-1\n"); } return0; }
相关文章推荐
- poj3687——Labeling Balls(拓扑排序)
- poj 3687 Labeling Balls
- POJ 3687--Labeling Balls【拓扑排序 && 逆序拓扑 && 输出在拓扑排序中的位置】
- POJ 3687 Labeling Balls (逆向建边)
- POJ 3687 Labeling Balls (反向拓扑排序)
- POJ-3687-Labeling Balls-(求最小字典序拓扑序列)逆向建图-拓扑排序
- Labeling Balls(poj 3687)
- 【poj】3687 Labeling Balls【拓扑排序】
- Poj 3687 Labeling Balls[拓扑排序]
- poj_3687 Labeling Balls
- poj 3687 Labeling Balls【拓扑排序 输出元素在拓扑序列中的位置】
- POJ 3687 Labeling Balls
- POJ 3687 Labeling Balls
- POJ 3687 Labeling Balls-拓扑排序
- POJ 3687 Labeling Balls (拓扑排序)
- POJ 3687:Labeling Balls(优先队列+拓扑排序)
- POJ 3687 Labeling Balls
- POJ 3687 Labeling Balls
- poj 3687 Labeling Balls
- poj 3687 Labeling Balls ( 拓扑排序 )