洛谷 P2015:二叉苹果树 ← 有依赖的背包问题

【题目来源】
https://www.luogu.com.cn/problem/P2015

【题目描述】
有一棵苹果树,如果树枝有分叉,一定是分二叉(就是说没有只有一个儿子的结点)。
这棵树共有 N 个结点(叶子点或者树枝分叉点),编号为 1∼N,树根编号一定是 1。
我们用一根树枝两端连接的结点的编号来描述一根树枝的位置。下面是一颗有 4 个树枝的树:

cpp 复制代码
2   5
 \ / 
  3   4
   \ /
    1

现在这颗树枝条太多了,需要剪枝。但是一些树枝上长有苹果。
给定需要保留的树枝数量,求出最多能留住多少苹果。
留住一个苹果的定义为苹果所在枝条直接与根相连或通过其他枝条间接与根相连。

【输入格式】
第一行 2 个整数 N 和 Q,分别表示表示树的结点数,和要保留的树枝数量。
接下来 N−1 行,每行 3 个整数,描述一根树枝的信息:前 2 个数是它连接的结点的编号,第 3 个数是这根树枝上苹果的数量。

【输出格式】
一个数,最多能留住的苹果的数量。

【输入样例】
5 2
1 3 1
1 4 10
2 3 20
3 5 20

【输出样例】
21

【数据范围】
1⩽Q<N⩽100,每根树枝上的苹果 ⩽3×10^4。

【算法分析】
● 有依赖的背包(树形背包)核心是物品间存在选子必选父的单向依赖关系,依赖结构通常为森林或多叉树,主流解法为树形 DP 结合分组背包自底向上合并;若题目中是双向强依赖、互相绑定的物品组(选其一必全选),则可先用并查集将连通块缩为超级物品,再套用普通 01 背包求解,两种思路对应不同依赖模型,共同构成完整解法体系。

● 有依赖的背包 / 树形背包 = 选儿子必须先选爹 + 把每个子树当成一组物品

● 邻接表:https://blog.csdn.net/hnjzsyjyj/article/details/155789364

● 核心代码解析
(1)fuk 表示在以 u 为根的子树中,保留 k 根树枝能得到的最大苹果数。
(2)fuj=max(fuj,fuj-i-1+fvi+w) 中,j-i-1 表示留给自己其他子树的树枝。-1 表示必须保留 u->v 这一条树枝。

【算法代码】

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

const int N=105;
vector<pair<int,int>> g[N];
int f[N][N];
int n,V;

void dfs(int u,int fa) {
    for(auto t:g[u]) {
        int v=t.first;
        int w=t.second;
        if(v==fa) continue;
        dfs(v,u);
        for(int j=V; j>=1; j--) {
            for(int i=0; i<j; i++) {
                f[u][j]=max(f[u][j],f[u][j-i-1]+f[v][i]+w);
            }
        }
    }
}

int main() {
    memset(f,0,sizeof f);
    cin>>n>>V;
    for(int i=1; i<n; i++) {
        int x,y,cnt;
        cin>>x>>y>>cnt;
        g[x].push_back({y,cnt});
        g[y].push_back({x,cnt});
    }

    dfs(1,-1);
    cout<<f[1][V]<<endl;

    return 0;
}

/*
in:
5 2
1 3 1
1 4 10
2 3 20
3 5 20

out:
21
*/

【参考文献】
https://blog.csdn.net/hnjzsyjyj/article/details/159791882
https://blog.csdn.net/hnjzsyjyj/article/details/159616887
https://blog.csdn.net/hnjzsyjyj/article/details/159650172

相关推荐
dtq04241 小时前
C语言刷题数组5,6(求平均值,求最大值)
c语言·数据结构·算法
洛水水2 小时前
【力扣100题】81.寻找两个正序数组的中位数
数据结构·算法·leetcode
Coder-magician3 小时前
《代码随想录》刷题打卡day15:二叉树part05
数据结构·c++·算法
Darling噜啦啦3 小时前
二叉树与递归算法实战:从树结构到 LeetCode 爬楼梯,一文吃透前端数据结构与递归思维
前端·javascript·数据结构
Irissgwe3 小时前
算法的时间复杂度和空间复杂度
数据结构·c++·算法·c·时间复杂度·空间复杂度
qq_297574674 小时前
设计模式系列文章(基础篇第22篇):访问者模式——分离数据结构与操作,实现灵活扩展
数据结构·设计模式·访问者模式
云淡风轻~窗明几净4 小时前
角谷猜想的任意算法测试
数据结构·人工智能·算法
代码中介商4 小时前
关键路径解析:项目管理的工期奥秘
数据结构
love_muming5 小时前
链表每日一练
java·开发语言·数据结构·链表·idea·每日一练
玖玥拾5 小时前
C/C++ 数据结构(二)双向链表
c语言·数据结构·c++