POJ 1655 Balancing Act (树的重心裸题)

题意:给你一个无根树,让你找到树的重心,就是树的重心的裸题,现在说一下树的重心把,树的重心就是以树的重心为根得到一颗有根树,这颗树中,节点最多的那颗子树的节点数量最少。

思路:根据定义去写的话,我们先随便以一个点为根,自底向上的求出他的所有子树数量,之后遍历每一个点,找到子树节点值最大的最小的那个数就好了

#include <vector>
#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
const int maxn = 20000 + 10;
vector<int>G[maxn];
int Size[maxn] , p[maxn];
void dfs(int u, int fa)
{
    Size[u] = 1;
    p[u] = fa;
    for(int i = 0 ; i < G[u].size() ; i++)
    {
        int v = G[u][i];
        if(v == fa) continue;
        dfs(v,u);
        Size[u] += Size[v];
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n , u , v;
        scanf("%d",&n);
        memset(Size,0,sizeof(Size));
        for(int i = 0 ; i <= n ; i ++) G[i].clear();
        for(int i = 0 ; i < n - 1 ; i++)
        {
            scanf("%d%d",&u,&v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        dfs(1,0);
        int node = 0 , ans = maxn;
        for(int u = 1 ; u <= n ; u++)
        {
            int MAX = n - Size[u]; //看这里,如果按照以1为根节,那么u的子树就是Size[u],那么现在以u为根节点,那么他儿子方向的节点数是Size[u] ,父亲方向的节点数其实是n-Size[u] 
            for(int i = 0 ; i < G[u].size() ; i++) // 遍历儿子方向的子树大小 
            {
                int v = G[u][i];
                if(p[u] == v) continue;
                MAX = max(MAX,Size[v]);
            }
            if(MAX < ans)
            {
                ans = MAX;
                node = u;
            }
        }
        printf("%d %d\n",node,ans);
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值