树的重心

846. 树的重心


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

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

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

输入格式

第一行包含整数 \(n\),表示树的结点数。

接下来 \(n−1\) 行,每行包含两个整数 \(a\) 和 \(b\),表示点 \(a\) 和点 \(b\) 之间存在一条边。

输出格式

输出一个整数 \(m\),表示将重心删除后,剩余各个连通块中点数的最大值。

数据范围

\(1≤n≤10^5\)

输入样例

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

输出样例:

4
  • 时间复杂度:\(O(n)\)

代码

//树的重心
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n;
vector<int> adj[N];
bool v[N];
int s[N],pos,res=N;
void dfs(int x)
{
    v[x]=s[x]=1;
    int max_part=0;
    for(int &y:adj[x])
    {
        if(v[y])continue;
        dfs(y);
        s[x]+=s[y];
        max_part=max(max_part,s[y]);
    }
    max_part=max(max_part,n-s[x]);
    if(max_part<res)
    {
        res=max_part;
        pos=x;
    }
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    dfs(1);
    printf("%d",res);
    return 0;
}
上一篇:docker overlay网络跨主机通信——使用(OVS)打通网络


下一篇:IfcFlowControllerType