[题解] P2015 二叉苹果树(树形DP)

本文介绍了一种使用树形动态规划方法解决在树结构中选择m条边以获得最大总权值的问题。通过递归遍历树并考虑每个节点与其子节点之间的边的不同选择情况,实现了最优解的计算。

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

  题意:在一棵树上,每条边都有权值,保留m条边,使留下来的总权值最大。
  分析:很裸的树形DP,对于每一个节点,他的父节点可以选择给他分配0–m-1条边,取最大值即可。
  代码如下:

#include <bits/stdc++.h>
using namespace std;
vector < int > q[110];
vector < int > w[110];
int f[300][300];
int n,Q;
void work(int son,int father) {
    for(int i=0;i<q[son].size();i++) {
        int s=q[son][i];
        if(s==father) continue;//由于是无向图,所以如果搜到父亲就重新搜
        work(s,son);//首先一层层递归到最底层后才开始工作
        for(int j=Q;j>=0;j--) {
            for(int k=j-1;k>=0;k--) {
                f[son][j]=max(f[son][j],f[son][j-k-1]+f[s][k]+w[son][i]);//核心语句 为什么要是f[son][j-k-1]? 因为有1点花费在了边上,所以它能够传递下去的值就-1
            }
        }
    }
    return ;
}
int main() {
    int a,b,c;
    scanf("%d%d",&n,&Q);
    for(int i=1;i<n;i++) {
        scanf("%d%d%d",&a,&b,&c);
        q[a].push_back(b);//由于是双向边所以存两次
        q[b].push_back(a);
        w[a].push_back(c);//w[i]用来存储边的价值
        w[b].push_back(c);
    }
    work(1,0);
    printf("%d",f[1][Q]);
    return 0;
}

                               by:Chlince

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值