树上DP学习指南
前置芝士
树上选点
[problem description]
给定一棵树,树根为 1,每个点的点权为 \(V_i\) 。
你需要找出若干个点 Pi,使得:
- 每两个点 Px, Py 互不相邻;
- 每两个点 Px, Py 与树根的距离互不相同;
- 找出的点的点权之和尽可能大。
请输出找到的这些点的点权和的最大值。
[solved]
所以我们在更新结点时不仅要从子树的结点更新,还要从兄弟的子树结点更新
这时问题就来了,都可以从哪里更新,怎么更新
首先还是dp
dp[u][1] 表示选择u结点的u的最大值,dp[u][0]表示不选择u结点的u的最大值
这样答案就是看根节点就可以了 取max(dp[1][1] , dp[1][0])
然后再来看题目要求
首先是不选择该节点,我们可以从所有下一层结点的状态更新过来,因为不选择该节点所以就只有不能选择到根节点距离相同这一个限制
然后就是选择该节点的,我们要从下一层结点的状态中找出满足要求的更新过来,所以我们直接遍历该节点的所有儿子,
这样只需要删除dp[v][1](v是u的儿子, dp[v][1]表示选择他儿子的最大值这一状态)即可
为了减少时间复杂度,我们用multiset来存每一层可以转移的状态
这样可以直接找到最大值时间上O(n) –> O(logn)。