AC日记——Two poj 1849

本文介绍了一种使用树形动态规划的方法来解决特定类型的边权总和问题,通过计算树的直径来得出最优解。文章提供了一个完整的C++实现代码示例。

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

Two

 

思路:

  树形DP求直径;

  答案是边权总和*2-直径;

  dp[i][1]::以i为根的子树中最长的路径;

  dp[i][0]::以i为根的子树中次长的路径;

 

来,上代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

#define maxn 100005

int n,s,E[maxn<<1],V[maxn<<1],W[maxn<<1],cnt;
int head[maxn],dp[maxn][2],sum,ans=0;

inline void in(int &now)
{
    char Cget=getchar();now=0;
    while(Cget>'9'||Cget<'0') Cget=getchar();
    while(Cget>='0'&&Cget<='9')
    {
        now=now*10+Cget-'0';
        Cget=getchar();
    }
}

void dfs(int now,int fa)
{
    bool res=true;
    int pos=0,gs=0;
    for(int i=head[now];i;i=E[i])
    {
        if(V[i]==fa) continue;
        res=false,dfs(V[i],now);
        if(W[i]+dp[V[i]][0]>gs) gs=W[i]+dp[V[i]][0],pos=V[i];
    }
    if(res) return ;
    dp[now][0]=gs,gs=0;
    for(int i=head[now];i;i=E[i])
    {
        if(V[i]==fa||V[i]==pos) continue;
        if(W[i]+dp[V[i]][0]>gs) gs=W[i]+dp[V[i]][0];
    }
    dp[now][1]=gs,ans=max(ans,dp[now][1]+dp[now][0]);
}

int main()
{
    in(n),in(s);int u,v,w;
    for(int i=1;i<n;i++)
    {
        in(u),in(v),in(w),sum+=w*2;
        E[++cnt]=head[u],V[cnt]=v,W[cnt]=w,head[u]=cnt;
        E[++cnt]=head[v],V[cnt]=u,W[cnt]=w,head[v]=cnt;
    }
    dfs(s,0);
    cout<<sum-ans;
    return 0;
}

 

转载于:https://www.cnblogs.com/IUUUUUUUskyyy/p/6783168.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值