「快餐店」 题解
法一:基环树常规dp
和基环树直径一样分两种情况:
①:这个点选在树内
则找到这个树的根到最远的点(非树内)的距离,和根到最远的点(树内)的距离,两个加起来除以二就是答案。
②:这个点选在环上
由于是环,不是很好做,所以破环成链,然后考虑这个点选择 \([l, r]\) 中 \((r = l + len - 1)\) (\(len\):环的长度),容易知道 [最远的距离/选在i点] 的图像是一个单峰函数,所以只需找到第一个 最远点在 \([l, pos]\) 到 \(pos\) 的距离 > 最远点在 \([pos + 1, r]\) 到 \(pos\) 的距离。由于 \([l, r] \rightarrow [l + 1, r + 1]\) 只会使 最远点在 \([l, pos]\) 到 \(pos\) 的距离减小,最远点在 \([pos + 1, r]\) 到 \(pos\) 的距离增大,所以这是一个单调函数,因此我们可以用双指针的做法。
具体操作:
pos : 0
for l : 1 ~ len
r : l + len - 1
while dis (l, pos) < dis (pos + 1, r)
pos++
res = min (res, dis (l, pos - 1) + dis (pos, r) >> 1)
但是这个细节太多了, 所以我写了一会后放弃了,现在拿出来口胡,所以介绍另一种更漂亮的做法。
法二:结论
答案就是基环树的直径除以 \(2\).(相当于选在直径的中点)
首先证明如果选在直径的中点,那么最远的距离就是直径除以 \(2\)。
反证法:
如果最远的距离不是直径除以 \(2\),那么说明有一个点到选择的点的距离大于直径除以 \(2\)
如图,蓝线是直径,绿线是最远的距离
那么,直径就会是红色的这条线,与蓝线是直径矛盾。
现在来证明这是最优解。
反证法:假设这不是最优解
假设红线是最优解,那么由于图联通,所以选的点到蓝线一定有一条路径。
所以绿色路径大于红色路径路径的一半 \((直径 / 2 + \Delta > 非直径 / 2) (0 \leq \Delta)\),矛盾。
所以求出基环树的直径后,除以 \(2\) 就是答案
代码就咕了,因为求基环树的直径我写丑了。ee