求调,玄关!
查看原帖
求调,玄关!
878013
_Supernova楼主2024/8/3 19:18

WA on Test 3.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 4e5 + 5;
int n, f[N], siz[N], g[N], maxx[N], maxxx[N]; // maxx是u的所有儿子v中,f[v]最大值,maxxx是次大值 
// siz是子树大小,f,g含义如上课所讲 
vector <int> G[N];
int fat[N]; // 父亲 
void predfs(int u, int fa) {
	fat[u] = fa;
	siz[u] = 1;
	for (int v : G[u]) {
		if (v == fa) continue;
		predfs(v, u);
		siz[u] += siz[v];
		if (siz[v] <= n / 2) f[u] = max(f[u], siz[v]);
		else f[u] = max(f[u], f[v]); // 更新 f数组 
		if (f[v] >= maxx[u]) {
			maxxx[u] = maxx[u];
			maxx[u] = f[v];
		}
		else if (f[v] >= maxxx[u]) maxxx[u] = f[v];
		else ; // 更新最大值和次大值 
	}
	return ;
}
void dfs(int u, int fa) {
	for (int v : G[u]) {
		if (v == fa) continue;
		if (n - siz[v] <= n / 2) g[v] = max(g[v], n - siz[v]);
		g[v] = max(g[v], g[u]);
		if (f[v] == maxx[u]) g[v] = max(g[v], maxxx[u]);
		else g[v] = max(g[v], maxx[u]); // 更新g 
		dfs(v, u);
	}
	return ;
}
bool check(int u) {
	if (n - siz[u] - g[u] > (n / 2)) return false; // 外面不合法 
	for (int v : G[u]) {
		if (v == fat[u]) continue;
		if (siz[v] - f[v] > (n / 2)) return false; // 子树不合法 
	}
	return true;
}
int main(void) {
	scanf("%d", &n);
	for (int i = 1, x, y; i < n; ++i) {
		scanf("%d %d", &x, &y);
		G[x].push_back(y);
		G[y].push_back(x);
	}
	predfs(1, 0);
	dfs(1, 0);
	for (int i = 1; i <= n; ++i) {
		if (check(i)) printf("1 ");
		else printf("0 ");
	}
	return 0;
}
2024/8/3 19:18
加载中...