poj3107(树的重心)

本文深入探讨了如何通过树形动态规划算法来确定树的重心,详细解释了重心定义、状态转移方程以及使用注意事项。通过实例代码演示,直观展示了解决过程。

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

求树的重心。树的重心是指去掉重心之后剩下的子树的最大结点个数最少
树形DP,dp[i]表示以i为重心,剩下的子树的最大结点个数,状态转移dp[i] = max(dp[i], siz[j])。
注意用vector超时。

代码如下:

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<math.h>
#include<cstring>
#include<string>
#include<vector>

#define N 50005
#define inf 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 10e-6

using namespace std;
int n,tot;
int siz[N],dp[N],head[N];
struct node
{
    int next,v,w;//next邻接表中的下一条边的编号,v边所到达的点,w权值
}edge[N*2];
void addedge(int u,int v)
{
    edge[tot].next = head[u];
    edge[tot].v = v;
    head[u] = tot++;
}
void dfs(int u,int pa)
{
    siz[u] = 1;
    dp[u] = 0;
    for(int i = head[u]; i != -1; i = edge[i].next)
    {
        int v = edge[i].v;
        if(v == pa) continue;
        dfs(v,u);
        siz[u] += siz[v];
        dp[u] = max(siz[v],dp[u]);
    }
    dp[u] = max(dp[u], n-siz[u]);
}
int main()
{
    while(scanf("%d",&n) != EOF)
    {
        int i;
        memset(siz,0,sizeof(siz));
        memset(head,-1,sizeof(head));
        for(i = 1; i < n; i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            addedge(u,v);
            addedge(v,u);
        }
        tot = 0;
        dfs(1,0);
        int ans = inf;
        for(i = 1; i <= n; i++)     ans = min(ans,dp[i]);
        for(i = 1; i <= n; i++) if(ans ==  dp[i])   { printf("%d",i); break;}
        for(i = i+1; i <= n; i++)  if(ans == dp[i]) printf(" %d",i);
        printf("\n");

    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值