AtCoder Beginner Contest 291
ABCDEFG
AtCoder Beginner Contest 291 | ABC 吊打萌新珍貴錄像 | A~G 題解
Ex - Balanced Tree
其實兩個條件都比較有啓發性的意義。
- 樹上路徑和 \(\operatorname{LCA}\)。
- 重心。
從兩個條件入手都可以觀察到點分樹滿足性質,於是本題直接建立點分樹即可。
// 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;
}