树的重心(dfs的应用)(c++)个人记录向

这篇博客探讨了一种在树形结构中寻找中心点的方法。通过DFS深度优先搜索,遍历每个节点并计算去掉该节点后剩余连通部分的最大点数,最终找到这些最大值中的最小值作为树的中心。程序实现中使用链表存储树结构,并通过递归DFS函数计算每个节点的影响。博客内容涉及图论和算法设计,旨在解决数据结构问题。
摘要由CSDN通过智能技术生成

 这道题目的题意有点绕,就是说,一棵树,然后去点每一个点都找到他们剩下连通块中点数最大的,然后在这些最大的里面找到最小的那个,那个去掉的点就是树的中心。换句人话就是最大的里面最小的。

首先写一下主函数以及用链表的形式存储这棵树

 //可以用dfs来做这样的题目,因为dfs是深度搜索,一条路走到黑的,我们可以给dfs定义一个返回值,返回值表示的就是这个点以及它的子节点的总数是多少
#include<iostream>
#include<cstring>
using namespace std;

const int N=1e5+10,M=2*N;
int e[M],ne[M],idx,h[N];//e存被指向的那个节点,ne指向下一个被指向的节点,h是头节点
bool st[N];//用来记录有没有被搜索到
int ans=N;//因为要找到最小所以设计初值为N
int n;


void add(int a,int b)
{
    e[idx]=b;
    ne[idx]=h[a];
    h[a]=idx++;
}
int main()
{
    memset(h,-1,sizeof h);
    cin>>n;
    for(int i=1;i<n;i++)
    {
        int a,b;
        cin>>a>>b;
        add(a,b);
        add(b,a);
    }
    dfs(1);
    cout<<ans<<endl;
    return 0;
}

那么我们怎么来找到每个点去掉后的最大连通图呢,去掉一个点后,一般有三个连同的树,分别为它的左右子树,以及它的父树。我们可以先将它的左右子树进行比较,找出其中较大的,然后加上它自身1记作sum,然后用n也就是总数减去sum就是它的父树中点的个数。

这样我们设计dfs的时候给其设置一个返回值,这个返回值就是包括那个点本身的子树的点的数量


int dfs(int u)
{
    st[u]=true;//说明u这个点已经被搜索到了
    int sum=1,res=0;//定义sum代表其包括其子树的总数,res代表删去这个点,所剩余的连通图中最大的点数
    for(int i=h[u];i!=-1;i=ne[i])
    {
        int j=e[i];
        if(!st[j])
        {
            int t=dfs(j);//深度寻找,直至找到最后一个节点
            res=max(res,t);//比较左右子树的一个步骤如果有的话,因为for循环会找到左右子树
            sum+=t;//记录包括其自己的总数当然要加上左右子树
        }
    }
    res=max(res,n-sum);//选出来的较大的左右子树与其父树的个数进行比较
    ans=min(ans,res);//最大里面选最小的
    return sum;//最后返回包括u号点+其子树的个数,返回给上层统计
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值