ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

树的重心与树的直径

2019-09-07 16:55:48  阅读:264  来源: 互联网

标签:重心 int max dfs son ms ans 直径


也许更好的阅读体验

树的重心

树的重心的定义
找到这样一个节点,使以其作为根节点时,最大的子树所含节点数最少

解决方法很简单,随便扯一个节点作为根节点,然后算一个点时考虑完所有儿子后再考虑一下父亲作为子树的答案即可

两种打法

int dfs (int x,int fa,int m)
{
    son[x]=1,ms[x]=0;//ms max_num_of_son
    int tans=2000;
    for (int e=head[x];e;e=nxt[e]){
        if (to[e]==fa||vis[to[e]])  continue;
        int t=dfs(to[e],x,m);
        if (ms[tans]>ms[t]) tans=t;
        son[x]+=son[to[e]];
        ms[x]=max(ms[x],son[to[e]]);
    }
    ms[x]=max(ms[x],m-son[x]);
    if (ms[tans]>ms[x]) tans=x;
    return tans;
}

int ans;
void dfs (int x,int fa,int m)
{
    son[x]=1,ms[x]=0;
    for (int e=head[x];e;e=nxt[e]){
        if (to[e]==fa||vis[to[e]])  continue;
        dfs(to[e],x,m);
        son[x]+=son[to[e]];
        ms[x]=max(ms[x],son[to[e]]);
    }
    ms[x]=max(ms[x],m-son[x]);
    if (ms[ans]>ms[x])  ans=x;
    return ans;
}

树的直径

求树中最长的一条路径
求法也不难,考虑一个点作为直径拐弯的点
记下最大路径和次大路径
比较所有节点的两者之和即可

实现的话只需存下最大路径,然后比较当前路径加上最大路径即可
即看看当前路径是否是次大路径或者更大的路径

void dfs(int x,int fa) {
    f[x]=1;
    for (int e=head[x];e;e=nxt[e]){
        if (to[e]==fa)  continue;
        dfs(to[e],x);
        ans=max(ans,f[x]+f[to[e]]+w[e]);
        f[x]=max(f[x],f[to[e]]+w[e]);
    }
}

如有哪里讲得不是很明白或是有错误,欢迎指正
如您喜欢的话不妨点个赞收藏一下吧

标签:重心,int,max,dfs,son,ms,ans,直径
来源: https://www.cnblogs.com/Morning-Glory/p/11481659.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有