AtCoder Regular Contest 102 - D All Your Paths are Different Lengths (构造 二进制)

20 篇文章 0 订阅

https://arc102.contest.atcoder.jp/tasks/arc102_b

 

题意:

给你一个L,让你构造一张图,点数不超过20,边数不超过60。可以重边。

他的拓扑排序必须为1 2 3…… n,即边只能从小连到大。

这张图必须确切存在L条不同的边,长度分别为0,1,2,3……L-1.

L=<1e6

 

POINT:

如果L是1,2,4,8,16这种整二进制数,很好办。只要给i到i+1连上0和1<<(i-1)的两条边就可以。

问题出在把这个整二进制数处理完了之后,后面还有1怎么办。比如101101_{2}这个数(45)。

最前面的32很好办。就按照之前的方法可以构造完0到31。剩下来的1,4,8个数。

分别是(32),(33,34,35,36),(37,38,39,40,41,42,43)

这时候,加一条边i到n,长度为x,则会增加x,x+1,……,x+2^(i-1)-1那么多边。

所以 加 1-n 长度为32,   3-n 长度为33,   4-n长度为37。这三条边。

至于32,33,37这三个长度是怎么算的,看规律便能知晓。

 

#include <iostream>
#include <stdio.h>
#include <vector>
using namespace std;
struct node
{
	int u,v,w;
};

node a[70];
int cnt=0;
void add(int u,int v,int w)
{
	cnt++;
	a[cnt].u=u;a[cnt].v=v;a[cnt].w=w;
}
int main()
{

	int L;
	scanf("%d",&L);
	int tmp=L;
	int n=0;
	while(tmp){
		n++;
		tmp>>=1;
	}
	for(int i=1;i<n;i++){
		add(i,i+1,1<<(i-1));
		add(i,i+1,0);
	}
	int w=1<<(n-1),k=1;;
	while(L!=1){
		if(L&1) {
			add(k,n,w);
			w|=1<<(k-1);
		}
		k++;
		L>>=1;
	}
	printf("%d %d\n",n,cnt);
	for(int i=1;i<=cnt;i++){
		printf("%d %d %d\n",a[i].u,a[i].v,a[i].w);
	}


	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值