POJ ~ 1655 ~ Balancing Act (树的重心)

本文深入探讨了树的重心概念及其算法实现,介绍了如何通过计算找到一棵树的重心,即那个使得所有子树中最大子树节点数最少的点。通过具体代码示例,详细解释了如何处理多组测试数据,求解树的重心并输出重心位置及最大子树的节点数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述

题意

树的重心也叫树的质心。找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删去重心后,生成的多棵树尽可能平衡。
T组测试数据,每组输入N,然后输入N-1条边,求树的重心。输出重心和最大的子树节点数。

思路

模板

//#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
const int MAXN = 1e5+5;
const int INF = 0x3f3f3f3f;
int n, sz[MAXN], pre[MAXN];
vector<int> G[MAXN];
int dfs(int u, int fa)
{
    sz[u] = 1;
    pre[u] = fa;
    for (int i = 0; i < G[u].size(); i++)
    {
        int v = G[u][i];
        if (v != fa)
            sz[u] += dfs(v, u);
    }

    return sz[u];
}
int main()
{
    int T; scanf("%d", &T);
    while (T--)
    {
        scanf("%d", &n);
        for (int i = 0; i <= n; i++) G[i].clear();
        for (int i = 1; i < n; i++)
        {
            int u, v; scanf("%d%d", &u, &v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        dfs(1, -1);
        int ans = -1, MIN = INF;
        for (int u = 1; u <= n; u++)
        {
            int MAX = n - sz[u];
            for (int i = 0; i < G[u].size(); i++)
            {
                int v = G[u][i];
                if (v != pre[u])
                MAX = max(MAX, sz[v]);
            }
            if (MAX < MIN) MIN = MAX, ans = u;
        }
        printf("%d %d\n", ans, MIN);
    }
    return 0;
}
/*
1
7
2 6
1 2
1 4
4 5
3 7
3 1
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值