HDU6326 题解

题意:一棵树,除 \(1\) 节点外每个节点有一个怪兽。你初始在节点 \(1\),走到一个节点就必须打该节点怪兽。打节点 \(i\) 的怪兽会掉 \(a_i\) 血,打完后回 \(b_i\) 血。问至少初始多少血可以打完所有怪兽。

先考虑问题的弱化版,即可以在任何时间选择任意怪兽打的情况。

考虑贪心。显然的,先选择 \(a_i>b_i\) 的怪兽打一定是更优的。分别考虑 \(a_i>b_i\)\(a_i<b_i\) 的情况。

对于 \(a_i>b_i\),血量在打的过程中不断增加,可以证明先打 \(a_i\) 较小的怪是更优的。

对于 \(a_i<b_i\) 的情况,可以考虑时间倒流,先当于从末尾状态开始,掉 \(b_i\) 血,回 \(a_i\) 血。由 \(a_i>b_i\) 的情况,可以证明先打 \(b_i\) 较大的怪是更优的。

由于怪的 \(a_i,b_i\) 不发生改变,所以任意时刻怪 \(i,j\) 的优劣顺序不变,即所有的怪存在一个确定的优劣顺序。

可以发现以下事实:

考虑树上当前除根节点外的节点中最优的,记为 \(u\)。在 \(v=fa_u\) 被打败后打 \(u\) 一定是不劣的,因为若存在血量 \(x\),使得打 \(v\) 后打 \(v\neq u\) 可以完成,交换 \(u,v\) 一定使得操作序列更优。

所以,可以把这样的 \(u\) 合并到 \(v\) 上,表示一旦到达 \(v\) 立刻到达 \(u\)。合并后,\(a_v\) 的取值需要使得在血量为 \(a_v\) 时可以连续打 \(v\)\(u\),即 \(a_v=\max(a_v,a_v-b_v+a_u)\)\(b_v\) 则需要使得 \(b_v-a_v\) 与原本的 \(b_v-a_v+b_u-a_u\) 相等。不断合并点直到只剩下根节点,根节点的 \(a\) 即为答案。

具体实现上,用并查集维护点的合并情况。用 set 取当前最优点并插入删除常数太大,改用 priority_queue 维护,删除则记录一个标记数组,从 priority_queue 取节点时若被标记则跳过即可。

代码:https://www.luogu.com.cn/paste/ykvb09j2

posted @ 2024-06-19 17:15  tybbs  阅读(19)  评论(0编辑  收藏  举报