桂林电子科技大学第三届ACM程序设计竞赛 G 路径

本文介绍了一种使用树形动态规划的方法来解决寻找树中具有最大权重和的偶数边路径的问题。通过保留每个节点的奇数和偶数边情况的最大值,实现了高效求解。

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

链接:https://ac.nowcoder.com/acm/contest/558/G
来源:牛客网

小猫在研究树。
小猫在研究路径。
给定一棵N个点的树,每条边有边权,请你求出最长的一条路径,满足经过每个点最多一次,经过的边的条数为偶数,且边权和最大。
请输出这个最大的边权和。

输入描述:

第一行一个正整数N,表示节点个数。

接下来N−1行,第i行三个正整数

ui,vi,wi,表示第i条边连接点ui,vi,边权为wi。

输出描述:

一行一个正整数,表示最大的边权和。

输入

5
1 2 5
1 3 5
2 4 5
2 5 1

输出

10

备注:

1≤N≤10

5

,1≤w

i

≤10

9

,保证输入数据形成一棵树。

题意:一棵树上每条边有一个边权,然后叫你找出一个偶数条边的路径,要求权值最大
思路:首先这个很容易看出是树形dp,不用偶数条的时候我们就可以保留到每个点的最大值然后找出每个点的最大和次大之和即可
偶数我们怎么处理呢,我们这时候就要考虑到当前这个点奇数条和偶数条的情况,所以我们dp数组分开记录奇偶数情况
#include<bits/stdc++.h>
#define mod 5000000007
#define maxn 100005
using namespace std;
typedef long long ll;
struct sss
{
    ll x,z;
    sss(){};
    sss(int a,int b){x=a;z=b;}; 
};
vector<struct sss> mp[maxn];
int n;
long long mx;
ll dp[maxn][2];
void dfs(int x,int fa)
{
    dp[x][0]=0;
    dp[x][1]=-mod;
    for(int i=0;i<mp[x].size();i++){
        int y=mp[x][i].x;
        int z=mp[x][i].z;
        if(y==fa) continue;
        dfs(y,x);
        mx=max(mx,max(dp[x][0]+z+dp[y][1],dp[x][1]+z+dp[y][0]));//先取第一条,所以我们的dp[x][1]初值为-mod,后面再比较最大值
        dp[x][0]=max(dp[x][0],dp[y][1]+z);
        dp[x][1]=max(dp[x][1],dp[y][0]+z);
    }
    return;
}
int main(){
    ll x,y,z;
    cin>>n;
    for(int i=0;i<n-1;i++){
        cin>>x>>y>>z;
        mp[x].push_back(sss(y,z));
        mp[y].push_back(sss(x,z)); 
    }
    dfs(1,0);
    cout<<mx; 
}

 



转载于:https://www.cnblogs.com/Lis-/p/10706398.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值