树的重心

定义

  1. 树的重心也叫树的质心。对于一棵树n个节点的无根树,找到一个点,使得把树变成以该点为根的有根树时,最大子树的结点数最小。换句话说,删除这个点后最大连通块(一定是树)的结点数最小。剩余的节点必然不超过原来的n/2。

性质

  1. 树中所有点到某个点的距离和中,到重心的距离和是最小的,如果有两个重心,他们的距离和一样。
  2. 把两棵树通过一条边相连,新的树的重心在原来两棵树重心的连线上。
  3. 一棵树添加或者删除一个节点,树的重心最多只移动一条边的位置。
  4. 一棵树最多有两个重心,且相邻。

题意

问删除树的重心后,剩余的最大子树的大小


//本代码还未ac
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
vector<int> g[N];
int n, m, K;
int ans = 0x3f3f3f;
int sz[N];//子树大小

void dfs(int u, int fa) {
    sz[u] = 1;
    int tmp = 0; //记录删除u这个节点后 剩余的子树里最大的那棵的个数
    for (auto v:g[u]) {
        if (v == fa)continue;
        dfs(v, u);
        sz[u] += sz[v];
        tmp = max(tmp, sz[v]);
    }
    tmp = max(tmp, n - sz[u]);//父节点的那个分支

    if (tmp < ans) { 
        ans = tmp;
    } //删掉树的重心后 剩余的最大联通块的节点数应该是最小的
}

int main() {
    ios::sync_with_stdio(0);

    cin >> n;
    for (int i = 1, u, v; i <= n; ++i) {
        cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dfs(1, 0);
    cout << ans << endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值