POJ 3687 Labeling Balls (逆向拓扑排序)

题意: N个球,从1~N编号,质量各不相同,给出小球间的质量关系(如给出a b  表示 a比b轻), 要求给每个球贴标签(此标签表示该小球为第几轻)。按编号输出每个球的标签。如果解不唯一,标签小的应该先分配给编号小的.(即取字典序最小的结果)

分析: 通过以下这组数据分析:

1

5   4

1   4

4   2

5   3

3    2

建图:  a->b表示编号为a的球重量<编号为b的球,   以下为正向建立拓扑图

 

模拟拓扑排序选择如下:

1.  当前要贴标签1,  可取出的小球编号为1, 5,   解不唯一,标签小的应该先分配给编号小的., 故取出1. 并给编号1的小球分配标签1;

    

2.   当前要贴标签2,  可取出的小球编号为4, 5,   解不唯一,标签小的应该先分配给编号小的., 故取出4. 并给编号4的小球分配标签2;

    

3. 当前要贴标签3, 可取出的小球编号为5, 解唯一, 故取出5, 给编号为5的小球分配标签3。

  依次类推, 分别给编号为3的小球分配标签4, 给编号为2的小球分配标签5.

故结果为:

小球编号:   1     2     3      4      5

相应标签:   1     5     4      2      3  (输出结果)

正确结果:   1     5     3      4      2   (这个结果是由先取编号1的小球, 再取编号5的小球, 再取编号3的小球, 再取编号4的小球, 最后取编号2的小球得出的)

明显15342字典序<15423. 故正向拓扑结果不能成立。

这个时候我们可以换个思路,逆向拓扑, 并且每次都先分配大标签, 并且将编号大的小球先取出, 这样就可以标签小的就可以分配给编号小的小球了.

具体过程不详述, 请看code:

#include<iostream>
#include<cstdio> 
#include<queue>
#include<cstring>
using namespace std;
const int maxn = 205;
int n,m;
int e[maxn][maxn], d[maxn], num[maxn];

int main()
{
	int T, i, j, k;
	//freopen("in.txt", "r", stdin);
	scanf("%d", &T);
	while(T--){
		memset(e, 0, sizeof(e));
		memset(d, 0, sizeof(d));
		int a, b;
		scanf("%d %d", &n, &m);
		for(i=1; i<=m; i++){
			scanf("%d %d", &a , &b);
			if(!e[b][a]){//反向建图
				e[b][a] = 1;//连接
				d[a]++;//度
			}
		}
		/********solve***********/
		bool flag=false;
		for(i=n; i>=1; i--){//从最大的标签开始贴
			for(j=n; j>=1; j--){//取当前未被分配标签的小球中编号最大的小球
				if(!d[j]){
					num[j]=i;//当前为选出的编号为j的小球分配标签i
					d[j]--;
					for(k=1;k<=n;k++){
						if(e[j][k]){
							d[k]--;
						}
					}
					break;
				}
			}
			if(j==0){
				flag=true;
			}
		}
		if(!flag){
			for(i=1; i<=n; i++){
				if(i!=1) printf(" ");;
				printf("%d", num[i]);
			}
			printf("\n");
		} else{
			printf("-1\n");
		}

	}
	return 0;
}






  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值