POJ-1655 Balancing Act(树的重心)
题目链接:Balancing Act
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int N = 100010;
const int INF = 0x3f3f3f3f;
int n, ans;
int sz[N]; //表示x子树的节点数
int mx[N]; //表示删去x之后的最大子树节点数
vector<int> e[2 * N];
void init() {
for (int i = 0; i < N; i++) e[i].clear(), sz[i] = mx[i] = 0;
ans = 0, mx[0] = INF; //0号节点设为无穷大
}
void dfs(int u, int fa) {
sz[u] = 1;
for (int i = 0; i < e[u].size(); i++) {
int v = e[u][i];
if (v == fa) continue;
dfs(v, u);
sz[u] += sz[v]; //搜索完x的节点数+=(x的子节点)y的子节点数
mx[u] = max(mx[u], sz[v]); //max(mx[x], x的子节点数)mx[u]的更新u本身是不会计算在内的
}
mx[u] = max(mx[u], n - sz[u]); //max(mx[x], n-x的子节点数)
if (mx[u] < mx[ans]) ans = u; //最小最大子树节点数
if (mx[u] == mx[ans] && u < ans) ans = u; //编号最小
}
void solve() {
init();
scanf("%d", &n);
for (int i = 1; i < n; i++) {
int u, v; scanf("%d %d", &u, &v);
e[u].push_back(v), e[v].push_back(u);
}
dfs(1, 0);
printf("%d %d
", ans, mx[ans]);
}
int main() {
int T; scanf("%d", &T); while (T--) solve();
return 0;
}