P3629 [APIO2010] 巡逻
大佬们都用数学推理,求两遍直径的方法。然而我并不会这么高级的方式。
思路
对于 \(k=1\) 的情况,加上一条边时,树上出现了一条环且长为 \(T\),环上的原路径都可以少走一遍,再算上新路径要走一遍。此时答案为 \(2 \times (n-1) - (T-1) + 1\)。
我们需要令 \(T-1\) 尽可能大,即原路径的那条链尽可能长,那么应该取树的直径。
对于 \(k=2\) 的情况,加上两条边会出现两条环。由于出现的每条环长度比所选链长多一,所以只考虑树上所选链的情况即可。
若想使总步数尽可能小,那么选出的两条链要尽可能多的覆盖树上的路径。且在每条环上,我们都会把环上所有边都经过一遍再走出这条环,所以两条链的重合部分要尽可能少。
贪心地取,我们取到的其中一条链一定是树的直径。
第二条链在取的时候我们分类讨论。
设第一条链选出的点为 \(u\in S\)。
如果第二条链与第一条链没有重叠部分,那么我们对每个 \(u\) 求其子树直径即可。
如果第二条链与第一条链有重叠部分,那么我们将这条链分为一段重合部分、和两段非重叠部分。
(图片)
那么链最长
实际答案应该是 \(2 \times (n-1) - S_{并}+S_{重}+2\)。