树的重心

定义

找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心。

性质

  1. 树中所有点到某个点的距离和中,到重心的距离和是最小的;如果有两个重心,那么他们的距离和一样。
  2. 找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心。
  3. 一棵树添加或者删除一个节点,树的重心最多只移动一条边的位置。
  4. 以这个点为根,那么所有的子树(不算整个树自身)的大小都不超过整个树大小的一半。
  5. 把两棵树连起来,新树的重心必定在原来两棵树的重心连线的路径上。

应用

求树的重心模板

void getG(int u,int last){
    int ret=0;
    sz[u]=1;
    for(int i=head[u];i;i=e[i].next){
        int v=e[i].to;
        if(v==last)continue;
        getG(v,u);
        ret=max(ret,sz[v]);
        sz[u]+=sz[v];
    }
    ret=max(ret,n-sz[u]);
    if(ret<szG){
        szG=ret;
        G=u;
    }
}

\(O(n)\) 求一棵树中所有子树的中心

void dfs(int u,int last){
    G[u]=u;
    sz[u]=1;
    for(int i=head[u];i;i=e[i].next){
        int v=e[i].to;
        if(v==last)continue;
        dfs(v,u);
        sz[u]+=sz[v];
    }
    for(int i=head[u];i;i=e[i].next){
        int v=e[i].to;
        if(v==last)continue;
        if((sz[v]<<1)>sz[u]){
            G[u]=G[v];
        }
    }
    while(((sz[u]-sz[G[u]])<<1)>sz[u]){
        G[u]=fa[G[u]];
    }
}

转载于:https://www.cnblogs.com/BlogOfchc1234567890/p/10409086.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值