题目链接

题目

题目描述

有一棵二叉苹果树,如果数字有分叉,一定是分两叉,即没有只有一个儿子的节点。这棵树共N个节点,标号1至N,树根编号一定为1。

我们用一根树枝两端连接的节点编号描述一根树枝的位置。一棵有四根树枝的苹果树,因为树枝太多了,需要剪枝。但是一些树枝上长有苹果,给定需要保留的树枝数量,求最多能留住多少苹果。

输入描述

第一行两个数N和Q,N表示树的节点数,Q表示要保留的树枝数量。

接下来N-1行描述树枝信息,每行三个整数,前两个是它连接的节点的编号,第三个数是这根树枝上苹果数量。

输出描述

输出仅一行,表示最多能留住的苹果的数量。

示例1

输入

5 2
1 3 1
1 4 10
2 3 20
3 5 20

输出

21

备注

对于 \(100 \%\) 的数据,\(1 \le Q \le N \le 100,N \neq1\) 每根树枝上苹果不超过30000个。

题解

知识点:树形dp,背包dp。

这是一道经典的树上背包,因为每个点所在子树都可以分配一个边数(体积),并在这种情况下得到最值,而每次选的时候每个子节点都是不确定边数(体积)的,因此是个分组背包,每组都有不同的体积对应的贡献可选,只能选一个。

设 \(dp[u][i]\) 表示以 \(u\) 为根节点的子树,有 \(i\) 条边(包括子树头顶上连着父节点的边)的时候的最大苹果数。有转移方程:

\[dp[u][i] = \max (dp[u][i],dp[u][i-j] + dp[v][j-1]+w)
\]

表示为从子节点 \(v\) 的子树选取 \(j-1\) 条边,而子树需要头顶上还需要一条边连着父节点,因此原来的 \(u\) 的子树需要有 \(i-j\) 条边,再算上这条边的贡献 \(w\) ,加在一起就是当前情况的价值。注意这是一个滚动数组,总边数 \(i \in [1,q]\) 需要倒序遍历(\(i = 0\) 是 \(0\)),而选的 \(j \in [1,i]\) 相当于一个组中不同物品体积,正序即可。

由于这个背包都是正整数贡献的,默认 \(0\) 即可,放空气肯定没放物品贡献多。

时间复杂度 \(O(nq^2)\)

空间复杂度 \(O(nq)\)

代码

#include <bits/stdc++.h>

using namespace std;

int n, q;
vector<pair<int, int>> g[107];
int dp[107][107]; void dfs(int u, int fa) {
for (auto [v, w] : g[u]) {
if (v == fa) continue;
dfs(v, u);
for (int i = q;i >= 1;i--) {///体积,在u点滚动一个分组背包,i表示共多少边
for (int j = 1;j <= i;j++)///每个子树都可以选j-1条边,加上子树链接根节点共j条(j=0即背包前,已包含)
dp[u][i] = max(dp[u][i], dp[u][i - j] + dp[v][j - 1] + w);
}
}
} int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n >> q;
for (int i = 1;i < n;i++) {
int u, v, w;
cin >> u >> v >> w;
g[u].push_back({ v,w });
g[v].push_back({ u,w });
}
dfs(1, 0);
cout << dp[1][q] << '\n';
return 0;
}

NC50505 二叉苹果树的更多相关文章

  1. CJOJ 1976 二叉苹果树 / URAL 1018 Binary Apple Tree(树型动态规划)

    CJOJ 1976 二叉苹果树 / URAL 1018 Binary Apple Tree(树型动态规划) Description 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的 ...

  2. Luogu_2015 二叉苹果树

    题目链接 SB 裸题……就是想随便挂在这里……同样的题还有 Luogu_2014 选课. Luogu_2015 二叉苹果树 #include <queue> #include <cs ...

  3. 二叉苹果树|codevs5565|luoguP2015|树形DP|Elena

    二叉苹果树 题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的 ...

  4. P2015 二叉苹果树

    P2015 二叉苹果树 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接 ...

  5. Loj10153 二叉苹果树

    题目描述 有一棵二叉苹果树,如果数字有分叉,一定是分两叉,即没有只有一个儿子的节点.这棵树共 NN 个节点,标号 11 至 NN,树根编号一定为 11. 我们用一根树枝两端连接的节点编号描述一根树枝的 ...

  6. 洛谷 P2015 二叉苹果树 (树上背包)

    洛谷 P2015 二叉苹果树 (树上背包) 一道树形DP,本来因为是二叉,其实不需要用树上背包来干(其实即使是多叉也可以多叉转二叉),但是最近都刷树上背包的题,所以用了树上背包. 首先,定义状态\(d ...

  7. 洛谷p2015二叉苹果树&yzoj1856多叉苹果树题解

    二叉 多叉 有一棵苹果树,如果树枝有分叉,可以是分多叉,分叉数k>=0(就是说儿子的结点数大于等于0)这棵树共有N个结点(叶子点或者树枝分叉点),编号为1~N,树根编号一定是1.我们用一根树枝两 ...

  8. P2015 二叉苹果树,树形dp

    P2015 二叉苹果树 题目大意:有一棵二叉树性质的苹果树,每一根树枝上都有着一些苹果,现在要去掉一些树枝,只留下q根树枝,要求保留最多的苹果数(去掉树枝后不一定是二叉树) 思路:一开始就很直接的想到 ...

  9. [Luogu2015]二叉苹果树(树形dp)

    [Luogu2015] 二叉苹果树 题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. ...

  10. loj10153二叉苹果树

    有一棵二叉苹果树,如果数字有分叉,一定是分两叉,即没有只有一个儿子的节点.这棵树共 N 个节点,标号 1 至 N,树根编号一定为 1. 我们用一根树枝两端连接的节点编号描述一根树枝的位置.一棵有四根树 ...

随机推荐

  1. 超全面总结Vue面试知识点,助力金三银四

    前言 本文会对Vue中一些常见的重要知识点以及框架原理进行整理汇总,意在帮助作者以及读者自测Vue的熟练度以及方便查询与复习.金三银四的到来,想必vue会是很多面试官的重点考核内容,希望小伙伴们读完本 ...

  2. Python定位错误:段错误 (核心已转储)

    技术背景 在各种编程语言中都有可能会遇到这样一个报错:"段错误 (核心已转储)".显然是编写代码的过程中有哪里出现了问题,但是这个报错除了这几个字以外没有任何的信息,我们甚至不知道 ...

  3. 0xGame 2023【WEEK1】Crypto全解

    What's CBC? 题目信息 from Crypto.Util.number import * from secret import flag,key def bytes_xor(a,b): a, ...

  4. CSS : div 高度为0的三种情况

    1, css 样式没正确绑定 ( 也就是没有设置高度 ) 2, 子元素 浮动 ( float ) 3, 子元素 绝对定位 ( position : absolute )

  5. JavaScript - input 上传图片 并展示 (食用简单)

    <!DOCTYPE html> <html lang="en">   <head>     <meta charset="UTF ...

  6. [转帖]Unix Domain Socket– IPC通信机制

    什么是Unix Domain Socket 基于socket的框架上发展出一种IPC机制,就是UNIX Domain Socket.虽然网络socket也可用于同一台主机的进程间通讯(通过loopba ...

  7. [转帖]Linux系统安装之后,如何调节CPU性能策略

    https://baize.cc/posts/efc.html#:~:text=Linux%E7%B3%BB%E7%BB%9F%E5%AE%89%E8%A3%85%E4%B9%8B%E5%90%8E% ...

  8. [转帖]iptables 执行清除命令 iptables -F 要非常小心的

    使用 /sbin/iptables -F 要小心,搞不好,你就马上同服务器断开连接了 以下是来自 http://wiki.ubuntu.org.cn/IptablesHowTo 上的说明 可以通过/s ...

  9. 将自签名创建的ca证书 添加到linux的授信证书列表的办法

    第一步: 将ca 证书 从cert 格式转换成pem格式 openssl x509 -in ca.crt -out ca.pem -outform PE 第二步: 将ca 证书导入至系统中来 cat ...

  10. Operating.System.Concepts.10th.Edition中文翻译

    <操作系统概念>是一本很好的书,主要介绍了操作系统的各个层面的概念,包含CPU调度,内存处理,文件系统等,目前已经出到第10版,是一本非常经典的书籍,从第1版至今被国内外众多高校选作教材, ...