AtCoder Beginner Contest 291

AtCoder Beginner Contest 291

ABCDEFG

AtCoder Beginner Contest 291 | ABC 吊打萌新珍贵录像 | A~G 题解

Ex - Balanced Tree

其实两个条件都比较有启发性的意义。

  1. 树上路径和 \(\operatorname{LCA}\)
  2. 重心。

从两个条件入手都可以观察到点分树满足性质,于是本题直接建立点分树即可。

// Problem: Ex - Balanced Tree
// URL: https://atcoder.jp/contests/abc291/tasks/abc291_h
// Group: AtCoder - AtCoder Beginner Contest 291(Sponsored by TOYOTA SYSTEMS)
// Time: 2023-02-26 20:00
// Author: lingfunny

#include <bits/stdc++.h>
using LL = long long;
using uint = unsigned;
using namespace std;
const int mxn = 1e5 + 10;

int n, fa[mxn];
vector<int> G[mxn];

int mxsz[mxn], sz[mxn], rt, allcnt;
bitset<mxn> vis;

void calsiz(int u, int fa) {
	mxsz[u] = sz[u] = 1;
	for (int v : G[u])
		if (!vis[v] && v != fa) {
			calsiz(v, u);
			sz[u] += sz[v];
			mxsz[u] = max(mxsz[u], sz[v]);
		}
	mxsz[u] = max(mxsz[u], allcnt - sz[u]);
	if (mxsz[u] <= mxsz[rt]) rt = u;
}

void dfz(int u) {
	vis[u] = 1;
	for (int v : G[u])
		if (!vis[v]) {
			allcnt = sz[v], rt = 0;
			calsiz(v, 0), calsiz(rt, 0);
			fa[rt] = u, dfz(rt);
		}
}

signed main() {
	scanf("%d", &n), mxsz[0] = mxn;
	for (int i = 1, u, v; i < n; ++i) {
		scanf("%d%d", &u, &v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	allcnt = n, calsiz(1, 0), calsiz(rt, 0), fa[rt] = -1, dfz(rt);
	for (int i = 1; i <= n; ++i) printf("%d%c", fa[i], " \n"[i == n]);
	return 0;
}
posted @ 2023-02-27 08:06  lingfunny  阅读(272)  评论(1编辑  收藏  举报