bzoj 3391: [Usaco2004 Dec]Tree Cutting网络破坏

题目链接


【想说的话】

果然我还是比较喜欢树


【题解】

dfs一遍计算出以1为根,每个点的子树节点和,最大的子树节点数

然后1到n扫一遍,注意由那个点的父亲组成的子树,n-sum[x]就行了


【代码】

#include<bits/stdc++.h>

#define MAXN 10010

typedef long long ll;

using namespace std;

inline int rd(){
	int x=0,y=1;char c=getchar();
	while(c<'0' || c>'9'){if(c=='-')y=-y;c=getchar();}
	while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
	return x*y;
}

int n;
vector<int>v[MAXN];
int sum[MAXN],Max[MAXN];

void dfs(int x,int fa){
	sum[x]=1;
	for(int i=0; i<v[x].size(); i++){
		int to=v[x][i];
		if(to==fa)continue;
		dfs(to,x);
		sum[x]+=sum[to];
		Max[x]=max(Max[x],sum[to]);
	}
}

int main(){
	n=rd();
	for(int i=1; i<n; i++){
		int x=rd(),y=rd();
		v[x].push_back(y);
		v[y].push_back(x);
	}
	dfs(1,0);
	bool f=false;
	for(int i=1; i<=n; i++){
		if(max(Max[i],n-sum[i])<=n/2){
			f=true;
			printf("%d\n",i);
		}
	}
	if(!f)puts("NONE");
	
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值