AtCoder Beginner Contest 291
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;
}
本文来自博客园,作者:lingfunny,转载请注明原文链接:https://www.cnblogs.com/lingfunny/p/17158412.html