DP求树的重心

时间:2021-09-11 21:23:46
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;
const int maxx =  200000+5;
vector<int>G[maxx];
int d[maxx];//保存的是当前节点的儿子节点数目
int vis[maxx];
int sum,num,n;
void dfs(int x)
{
    vis[x]=1;
    int num_son=1;
    for (int i=0; i<G[x].size(); i++)
    {
        int now=G[x][i];//当前访问的节点
        if(!vis[now]) //如果没有访问
        {
            dfs(now);//DFS
            d[x]+=(d[now]+1);//D[now]保存的是now的儿子节点个数,+1就是当前节点的儿子节点个数
            num_son=max(d[now]+1,num_son);//取大的
        }
    }
    num_son=max(num_son,n-d[x]-1);
    if (num_son<sum || (num_son==sum && x<num))//维护
    {
        sum=num_son;
        num=x;
    }
    return ;
}
int main()
{
    int t,u,v;
    scanf("%d",&t);
    while(t--)
    {
        memset(vis,0,sizeof(vis));
        memset(d,0,sizeof(d));
        for (int i=1; i<=n; i++)
        {
            G[i].clear();
        }
        memset(vis,0,sizeof(vis));
        scanf("%d",&n);
        sum=n;
        num=1;
        for (int i=1; i<n; i++)
        {
            scanf("%d%d",&u,&v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        dfs(1);
        printf("%d %d\n",num,sum);
    }
    return 0;
}