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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章