TPVJ水题

当前位置:/p/1331

P1331 sdlwwlp分饼
时间: 1000ms / 空间: 131072KiB / Java类名: Main

描述

sdlwwlp要和WD分一张大大大饼,奇怪的是这张饼竟然是树状的(@_@,像风铃一样),每个“节点"都像一张比较小的饼,中间用线穿了起来,形成了一张严格的树状图,现在他们两个为了公平起见,需要切断一条边把这张饼分成大小相似的两份,现在给定对饼的描述,请你计算分成两块的话,两块重量的差最小是多少(已知所有“节点”重量相同,“边”重量忽略)。
现在sdlwwlp看的眼花缭乱,不得不向你求助,给出节点和边的信息,请您写一个程序帮助傻傻的sdlwwlp分饼。

输入格式

第一行有一个个整数n,m分别表示“节点”个数。
第2..n行(大家不会不知道n个结点树有n-1条边吧?)每行有两个数a,b,表示编号a,b的两个“节点”间有“边”相连。

输出格式

若干行,每行一个数,可以切的边的序号(边的序号即边在输入中的位置,如果有多个最优的解,按序号从小到大输出)。

测试样例1

输入

7
1 2
4 2
3 1
5 2
3 6
7 6

输出

1
3

备注

样例解释:
切断第1条“边”(即1,2之间的边),可以把饼分成[1,3,6,7]和[2,4,5]两部分重量差1
或者是切断第3条,可以分成[3,6,7]和[1,2,4,5]两部分重量差1
数据范围:
对于30%的数据,n<=500;

对于全部数据,n<=40000.

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn = 400000+10;
int e,to[maxn],be[maxn],ne[maxn];
void add(int x,int y){
	to[++e] = y;
	ne[e] = be[x];
	be[x] = e;
}
bool p[maxn];
int size[maxn],deep[maxn];
void dfs(int x){
	p[x] = 1;
	for(int i = be[x];i;i = ne[i]){
		int v = to[i];
		if(!p[v]){
			deep[v]=deep[x]+1;
			dfs(v);
			size[x]+=size[v]+1;
		}
	}
}
struct T{
	int u,v;
}a[maxn];
struct TT{
	int id,z;
}tmp[maxn];
bool cmp(TT l,TT r){
	return l.z==r.z?l.id<r.id:l.z<r.z;
}
int main(){
	int i,j,k,m,n;
	scanf("%d",&n);
	for(i = 1;i<=n;i++)
	for(i = 1;i<=n-1;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		add(x,y);
		add(y,x);
		a[i].u=x,a[i].v=y;
	}
	dfs(1);
	int cnt=0;
	for(i = 1;i<=n-1;i++){
		if(size[a[i].u]&&size[a[i].v]){
			int ans1=n;
			if(deep[a[i].u]<deep[a[i].v])ans1=size[a[i].v]+1;
			else ans1=size[a[i].u]+1;
			tmp[++cnt].z=abs(n-ans1-ans1);
			tmp[cnt].id=i;
		}
	} 
	sort(tmp+1,tmp+cnt+1,cmp);
	int line=tmp[1].z;
	printf("%d\n",tmp[1].id);
	for(i=2;i<=cnt;i++)if(tmp[i].z==line)printf("%d\n",tmp[i].id);
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值