看似简单,但是开始做的时候,才发现有一些复杂的情况。比如,当一个节点被杀后,如果它的子树中还存在没有被杀掉的,可以全杀掉,以拖延整体的时间;对于任何一个节点,把它的儿子只杀掉一个,这不会迫使我必须杀掉它本身,而对于它的其它没有被杀的儿子,我还可以分别只杀掉它们的一个儿子,这也可以拖延时间;等等……
分析到最后,应该有这三个状态:
- diei:如果只杀以节点 i 为根的子树中的敌人,则 i 被杀的时间的最大值。
- noDiei:如果只杀以节点 i 为根的子树中的敌人,则最长可以拖延多久,使 i 还活着,并且我下一步还可以自由选择。可见,在这个时间之后,如果我再杀掉该子树中的任何一个敌人,就会引起连锁反映,迫使我无法选择,最终必须在时间 diei 杀掉 i。
- cleari:如果只杀以节点 i 为根的子树中的敌人,则当我在时间 diei 杀掉 i 之后,需要再花多少时间,把该子树中剩下的节点全杀光(其实就是所有剩下的节点的 T 值的总和)。
对于一个节点 v,求 diev、 noDiev 和 clearv 的过程分为以下三种情况:
1. 如果 v 是叶节点,则 diev = Tv, noDiev = clearv = 0。
2. 如果 v 只有一个子节点 x,则 noDiev = diex + clearx, diev = noDiev + Tv, clearv = 0。
3. 如果 v 有多个子节点,则:
- 先把每个子节点 i 的时间都拖延到 noDiei 。此时,v 子节点都还活着,并且下一步我可以自由选择。记此时的时间为 sumNoDie。
- 选取一个子节点 i,花 killi = (diei - noDiei) + cleari 的时间把 i 这棵子树全部清理掉。此时的时间是 sumNoDie + killi, v 的节点只死了一个,且下一步我还可以自由选择。在 v 的所有子节点中, sumNoDie + killi 的最大值就是 noDiev。
- 清理掉一个子节点 i 之后,再选一个子节点 j,用 killj = diej - noDiej 的时间杀掉 j。此时, v 已经有两个儿子被杀,必须立即花 Tv 的时间杀掉 v,那么 v 死时间就是 sumNoDie + killi + killj + Tv。在所有选取 i、 j 的方案中, sumNoDie + killi + killj + Tv 的最大值就是 diev。
- 最后求 clearv。在确定了以上 i、 j 的最佳选取方案,并在时间 diev 杀掉 v 之后,还需要花 clearj 的时间清理子树 j,然后对于 v 的其它剩下的子节点 x,再分别花 (diex - noDiex) + clearx 的时间把它们的子树都杀光。这些时间的总和就是 clearv。

