acwing-350. 巡逻
考点
- 树的直径
题解
1 |
|
思路
在不加路径之前,总的开销是2(n-1)
,因为每条路径都必须重复两次。
每加一条路径,路径两端点之间的原路径就会少走一次,新加的路径走一次(题目还说必须只能走一次),
所以选择树中的最长路径(直径)两端点进行连接以达到最佳效果。
假设原图如下,1
为起点,每条路径都要走两次(如箭头所示),直径为2 - 1 - 3 - 5 - 8
这一段
这里的边权均为非负,可以使用两次BFS进行求解直径。

当链接2
和8
两点后,2 - 1 - 3 - 5 - 8
整条直径只需要走一次,
假设这段直径长度为l1
,当前的路径开销就是2(n-1) - l1 + 1

将直径部分全部取反,再次寻找新直径(这里只能用树形dp求),会得到以下两种情况:
新的直径不包含上一条直径的任一条路径。
譬如
6 - 5 - 7
为新直径,那么将6
与7
连接建立新路,如图所示。假设新直径长度为
l2
,那么当前路径总开销为2(n-1) - l1 + 1 - l2 + 1
新的直径包含上一条直径的某一条路径。
假设新直径为
6 - 5 - 3 - 4
,连接6
与4
建立新路,如图所示。5 - 3
是两条直径的重叠部分,显然任意情况下它一定会被走两次;处理第一条直径时,它被计算走了一次,所以这里需要让它再被计算一次,这正是取反的妙处。
在这里,
新直径l2 = 1 (6到5的边权) - 1 (5到3的边权) + 1 (3到4的边权)
,减去
l2
不就相当于新直径其它部分正常减去一次,而5 - 3
部分再走一次。那么当前路径总开销依旧为
2(n-1) - l1 + 1 - l2 + 1