欢迎光临散文网 会员登陆 & 注册

[基础算法6] 树的重心

2023-07-11 23:08 作者:喵雕沙  | 我要投稿

题目描述

题目描述:
      给定一颗树,树中包含N个结点(编号从1-N),和N- 1 条无向边。请你找到树的重心,并输出 将重心删除后,剩余各个连通块中点数的最大值。
      重心定义:重心是指树中的一个结点,如果将这个点删除后,剩余各个连通块中点数的最大值最小,那么这个结点被 称为树的重心。
输入格式:  
     第一行包含整数N,表示 树的结点数,1<=N<=1e5 ,接下来N-1行,每行包含两个整数a和b,表示 a和b之 间存在一条边。
输出格式:
     输出一个整数 N,表示 将重心删除后,剩余各个连通块中点数的最大值。




样例输入 复制

9 1 4 1 2 2 6 2 5 6 3 6 7 7 9 7 8

样例输出 复制

4

来源/分类

树DP


程序:

#include <iostream>
using namespace std;
const int N=1e5+10;
bool vis[N];
int E[2*N],ne[2*N],h[N],id,ans=0x3f3f3f3f,n;
 
int dfs(int u)
{
    vis[u]=true;//标记u这个点被搜过
    int size=0;//记录u的最大子树的结点数
    int sum=1;//记录以u为根的子树的结点数
    for(int i=h[u];i!=0;i=ne[i])//i是边的编号
    {
        int j=E[i];//j是u的邻接点
        if(vis[j])
            continue;//避免向上查找
        int s=dfs(j);//s是以j为根的子树的结点数
        size=max(size,s);//记录u的最大子树的结点数
        sum+=s;//累加u的各个子树的结点数
    }
    ans=min(ans,max(size,n-sum));//更新答案
    return sum;//返回以u为根的子树的结点数
}
 
void add(int x,int y)//邻接表
{
    E[++id]=y;
    ne[id]=h[x];
    h[x]=id;
}//加边
 
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        int x,y;
        cin>>x>>y;
        add(x,y);
        add(y,x);//建图
    }
    dfs(1);
    cout<<ans<<endl;
    return 0;
}



[基础算法6] 树的重心的评论 (共 条)

分享到微博请遵守国家法律