P2015 二叉苹果树
题目描述
有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点)
这棵树共有 $N$ 个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1。
我们用一根树枝两端连接的结点的编号来描述一根树枝的位置。下面是一颗有4个树枝的树
1 | 2 5 |
现在这颗树枝条太多了,需要剪枝。但是一些树枝上长有苹果。
给定需要保留的树枝数量,求出最多能留住多少苹果。
输入格式
第1行2个数,$N$ 和 $Q$($1\leq Q\leq N,1<N\leq100$)。
$N$ 表示树的结点数,$Q$ 表示要保留的树枝数量。接下来 $N-1$ 行描述树枝的信息。
每行3个整数,前两个是它连接的结点的编号。第3个数是这根树枝上苹果的数量。
每根树枝上的苹果不超过30000个。
输出格式
一个数,最多能留住的苹果的数量。
输入输出样例
输入 #1
1 | 5 2 |
输出 #1
1 | 21 |
解决方案:
啊,树形dp入门题,按照深度优先的顺序去遍历树,在过程中进行dp。
很容易想到,按照每个节点作为一颗子树去进行dp,设状态为 $dp(u, i)$, 其中 $u$ 为当前节点的编号, $i$ 为当前节点为子树,保留 $i$ 条边,则 $dp(u, i)$ 显然为此时保留的最大的🍎的数量。
如何进行状态转移?既然都叫树形dp,肯定是由其子节点转移而来。想象一下这个dp过程,把 $u$ 的孩子节点的为根的子树一棵一棵加进来,去更新 $dp(u, i)$ 的值。
例如,假设要保留 3 条边,1 为根节点,1 的孩子节点为 2, 3, 4.
那么刚开始的时候 1 为根节点的树是空树,由于我们是按照深度优先去进行dp的,所以
$dp[i][j],i \in [2, 4], j \in [0, 3]$ 的值都是已经求出来的了。先把 2 为根的子树加进去,更新
$dp[1][j], j \in [0, 3]$, 然后再把 3, 4 一个一个加进去,利用孩子节点的dp值更新父节点,这就是此题的基本思路。
状态转移方程为:
其中:
其实这题完全可以拓展至多叉树或者无根树,代码几乎不需要变动。
更多细节看代码里的注释
代码
1 |
|
快开学了T_T