Acwing_算法基础_搜索与图论_树的重心

该问题涉及图论中的树概念,通过深度优先搜索(DFS)策略寻找树的重心,即删除某节点后导致最大连通块数量最小的节点。代码实现了一个DFS函数,遍历树的所有节点,计算每个节点删除后的子树规模和最大连通块大小,最终找出重心并返回删除它后剩余连通块的最大值。
摘要由CSDN通过智能技术生成

原题链接

给定一颗树,树中包含 n 个结点(编号 1∼n-1)和 n−1 条无向边。

请你找到树的重心,并输出将重心删除后,剩余各个连通块中点数的最大值。

重心定义:重心是指树中的一个结点,如果将这个点删除后,剩余各个连通块中点数的最大值最小,那么这个节点被称为树的重心。 

首先我们要知道,树是一种特殊的图,存储一棵树的的一条边a-b可以表示为a->b和b->a

这样就可以用我们之前存储链表的方式存储一棵树了。

而对于一棵树的某个节点而言,删除这个节点的后的连通块就是这个节点的子树,求其最大连通块的数目的最小值就是求子树的规模的最小值。

由此可以想到用dfs递归处理每一个没被搜索过的节点。求得删除某个节点后子树的规模和最大连通块的最小值。

代码如下:

#include<iostream>
#include<cstring>
using namespace std;
const int N=1e5+10;
int idx,h[N],e[N*2],ne[N*2],n;
//用来标记某个节点是否被搜索过
bool str[N];
int ans=N;
//链表插入,不过这次头节点有n个
void add(int a,int b){
    e[idx]=b;
    ne[idx]=h[a];
    h[a]=idx++;
}
int dfs(int u){
    //表示子树的节点数之和
    int sum=1;
    //表示删除该节点后,子树的最大值
    int res=0;
    str[u]=true;
    for(int i=h[u];i!=-1;i=ne[i]){
        int j=e[i];
        if(!str[j]){
            //递归求得子树的节点数
            int s=dfs(j);
            res=max(res,s);
            sum+=s;
        }
    }
    res=max(res,n-sum);
    ans=min(res,ans);
    return sum;
}
int main(){
    cin>>n;
    memset(h,-1,sizeof h);
    for(int i=0;i<n-1;i++){
        int a,b;
        cin>>a>>b;
        //插入两条边
        add(a,b),add(b,a);
    }
    dfs(1);
    cout<<ans;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值