POJ1655 Balancing Act(树的重心)

题意:

给你一棵树,求树的重心

如果有多个就输出序号最小的

思路:

树的重心就是以它为根的所有子树中节点最多的节点数最小

树形dp轻松可以解决

/* ***********************************************
Author        :devil
************************************************ */
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <stdlib.h>
using namespace std;
typedef long long LL;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const int N=2e4+10;
int n,sum[N],ans,p;
bool vis[N];
vector<int>eg[N];
void dfs(int u)
{
    int ma=0;
    vis[u]=1;
    for(int i=0;i<eg[u].size();i++)
    {
        int v=eg[u][i];
        if(vis[v]) continue;
        dfs(v);
        sum[u]+=sum[v]+1;
        ma=max(ma,sum[v]+1);
    }
    ma=max(ma,n-sum[u]-1);
    if(ma<ans||ma==ans&&u<p)
    {
        ans=ma;
        p=u;
    }
}
int main()
{
    //freopen("in.txt","r",stdin);
    int t,x,y;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        ans=inf;
        for(int i=1;i<=n;i++)
        {
            eg[i].clear();
            sum[i]=0;
            vis[i]=0;
        }
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&x,&y);
            eg[x].push_back(y);
            eg[y].push_back(x);
        }
        dfs(1);
        printf("%d %d
",p,ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/d-e-v-i-l/p/5703651.html