P1099 [NOIP 2007 提高组] 树网的核
题目描述
给定一棵树,定义点 \(u\) 到路径 \(P\) 的距离 \(D(u, P)=\min\{d(u, v)\}\), \(v\) 为路径 \(P\) 上的结点。
定义偏心距 \(\mathrm{ECC}(F)\):树上路径 \(F\) 最远的结点到路径 \(F\) 的距离,即
求路径 \(F\) 长度不超过 \(S\) 时的最小偏心距。
题解
引理 1:对于一棵所有边权均为正的树,如果其存在多条直径,则树上必存在一点 \( p \),使得所有直径均经过该点(简单来说,所有直径必交于至少一点)。
定理 1:对于一棵所有边权均为正的树,如果其存在多条直径,则各直径的中点(不一定恰好是某个节点,可能在某条边的内部)是唯一的(都是同一个点)。
引理 2.1:若两条直径有重叠的部分,则于重叠部分同一端点引出的两条直径的非重叠的部分的长度相等。
引理 2.2:若路径存在不位于直径上的部分,这条路径对应的偏心距一定不会比全部位于直径上的路径的偏心距的最小值更小。
定理 2:设在所有满足长度限制的路径中,取得最小偏心距的路径得到的偏心距为 \( \text{minBCC} \),则对于任意一条直径,都存在一条长度不超过 \( s \) 的路径 \( F \),使得 \( \text{BCC}(F) = \text{minBCC} \)。
做法1
归纳一下,设直径上的点分别为 \( a_1,a_2,\dots,a_k \),取的路径为 \( P(a_i,a_j) \ (i \leq j) \),则所求的偏心距为:
\( d_i \) 可以在求出直径后通过一次 DFS 求出。在二分偏心距 \( e \) 后,先找到直径的两端点 \( i, j \),使得 \( P(a_1,a_i), P(a_j,a_k) \leq e \),再判断路径长度是否超过限制,以及 \( \max_{i<p<j} d_{a_p} < e \) 是否满足。如果以上条件均满足,则找到一条可行的路径。
时间复杂度 \( O(n\log \sum w) \)。
做法2
分析了偏心距的组成后,我们发现没有必要再进行重复的 DFS,只需要在双指针过程中,动态更新
即可。
第一项区间最大值是经典的滑动窗口,可以用单调队列计算,其余两项前缀和即可。
时间复杂度 \( O(n) \)。
到这里就完了吗?时间复杂度确实到达了下限(输入就需要同样的时间复杂度),但是代码实现还能更简单。
注意到一个性质:\( \forall l \in [1,i], d_{a_l} \leq P(a_1,a_i) \),同样地,\( \forall l \in [j,k], d_{a_l} \leq P(a_j,a_k) \)。
证明:由直径是树上最长简单路径的性质,可以得到 \( d_{a_j} + P(a_j,a_i) \leq P(a_1,a_i) \),再结合 \( P(a_j,a_i) > 0 \),从而原命题得证。
于是我们将偏心距的表达式替换为
这一过程中我们加入的项都是不大于 \( P(a_1,a_i), P(a_j,a_k) \) 的项,在取max后不会影响结果。
\( \max_{1 \leq p \leq k} d_{a_p} \) 是定值,因此不必再使用单调队列!

浙公网安备 33010602011771号