AcWing 846. 树的重心

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010, M = N * 2;
int n;
int h[N], e[M], ne[M], idx;
int ans = N;//存最小的最大值
bool st[N];
void add(int a, int b) {
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}
//以u为根的子树中点的数量
int dfs(int u) {
    st[u] = true;//标记被搜过
    int res = 0;//把这个点删除之后,每一个连通块儿的最大值
    int sum = 1;//当前这个点算一个点
    for (int i = h[u]; i != -1; i = ne[i]) {
        int j = e[i];
        if (st[j]) continue;
        int s = dfs(j);//表示当前j子树的大小
        res = max(res, s);//求u的所有子树中数量最大的
        sum += s;//求以u为根节点的点数的总量
    }
    res = max(res, n - sum );//u上面的为n-sum,然后res取大
    //此时res存的是把u这个点删除之后最大的连通块儿的点数
    ans = min(ans, res);//和答案取min
    return sum ;//以u为根节点的子树中点的数量 
}
int main() {
    scanf("%d", &n);
    memset(h, -1, sizeof h);
    for (int i = 0; i < n - 1; i ++ ) {
        int a, b;
        scanf("%d%d", &a, &b);
        add(a, b), add(b, a);//因为是无向边,所以要加两条边 
    }
    dfs(1);
    printf("%d
", ans);
    return 0;
}
原文地址:https://www.cnblogs.com/QingyuYYYYY/p/11831947.html