题目链接:https://codeforces.com/contest/708/problem/C

题解:
有一个简化:我们把重心当成根,这样所有点,如果不是重心,问题只可能出在该点向上的那个“子树”中
考虑对每个点维护向上子树中的最大的不超过n/2的子树大小,这样最后判断一下去掉这个子树之后大小是否仍大于n/2即可
考虑设\(dp[i]\)为此值,使用换根dp,从x转移到儿子u
\(dp[u] = max(dp[x], otherson_dp, cut_x_u)\)
其中otherson_dp就是其它儿子的子树中最大的不超过n/2的子树大小,这个维护一个最大值和次大值即可(去掉当前儿子为最大值的情况)
cut_x_u就是去掉x->u边,u“向上”的子树的大小(如果该大小<=n/2,就计算,否则不计算)

代码:

// by SkyRainWind
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#define mpr make_pair
#define debug() cerr<<"Yoshino\n"
#define rep(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define pii pair<int,int>

using namespace std;

typedef long long LL;

const int inf = 1e9, INF = 0x3f3f3f3f, maxn=4e5+5;

int n;
vector<int>g[maxn];
int rt;
int sz[maxn], mx[maxn][2], ans[maxn], dp[maxn];

void dfs3(int x,int fat = -1){
	for(int u : g[x]){
		if(u == fat)continue;
		if(mx[x][0] == sz[u]){
			dp[u] = max(dp[u], mx[x][1]);
		}else dp[u] = max(dp[u], mx[x][0]);
		if(n - sz[u] <= n/2)dp[u] = max(dp[u], n - sz[u]);
		dp[u] =max(dp[u], dp[x]);
		dfs3(u, x);
	}
}

void dfs2(int x,int fat = -1){
	sz[x] = 1;
	for(int u : g[x]){
		if(u == fat)continue;
		dfs2(u, x);
		sz[x] += sz[u];
		if(sz[u] > n/2)continue;
		if(mx[x][0] <= sz[u]){
			mx[x][1] = mx[x][0];
			mx[x][0] = sz[u];
		}else if(mx[x][1] <= sz[u])mx[x][1] = sz[u];
	}
}

void dfs(int x,int fat = -1){
	sz[x] = 1;
	int iscen = 1;
	for(int u : g[x]){
		if(u == fat)continue;
		dfs(u, x);
		sz[x] += sz[u];
		if(sz[u] > n/2)iscen = 0;
	}
	if(n - sz[x] > n/2)iscen = 0;
	if(iscen)rt = x;
}

signed main(){
	scanf("%d",&n);
	for(int i=1;i<=n-1;i++){
		int x,y;scanf("%d%d",&x,&y);
		g[x].push_back(y), g[y].push_back(x);
	}
	dfs(1);
	dfs2(rt);
	dfs3(rt);
	for(int i=1;i<=n;i++){
		if(i == rt || (n - sz[i] - dp[i]) <= n/2)printf("1 ");
		else printf("0 ");
	}
	puts("");

	return 0;
}

原文地址:http://www.cnblogs.com/SkyRainWind/p/16806911.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性