【模板】POJ-1655 Balancing Act(树的重心)

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\n", ans, mx[ans]);
}

int main() {
    int T; scanf("%d", &T); while (T--) solve();
    return 0;
}
posted @ 2020-08-25 19:42  Nepenthe8  阅读(78)  评论(0编辑  收藏  举报