acwing-351. 树网的核
考点
- 树的直径
- 二分
- 单调队列
- 贪心
- 双指针
- 前缀和
题解
见思路
思路
首先证明两个直径的性质。
第一条,多条直径必相交于一点或一条公共路径。
假设A1
到B1
、A2
到B2
是两条不相交的直径,分别简写为l1
和l2
根据树的连通性原理,A2
肯定与l1
的某个点C1
连通,这样A2
才能与A1
、B1
连通
问题来了,d == a + b
,且都是最长长度(因为是直径),那么A1 - C1 - A2 - B2
这条路径不是更长吗?!
长度高达a + c + d
,相当于a + b + a + c
,远大于a + b
,
这与直径的定义相悖,得证。

第二条,任意两个同一侧的直径端点到相同直径分叉点的距离均相等。
假设有直径A1 - C - D - B1
,还有直径A2 - C - D - B2
,CD
部分是共有的,长度设为t
。
假设不平分,那么假设a > b
,d > c
,
显然得到a + d + t > b + c + t
,也就是A2 - C - D - B1
大于A1 - C - D - B2
,这与直径的定义相悖。
所以a
一定等于c
,b
也一定等于d
。
证毕。

概括一下题意:
选一条直径,直径上选一段路径。
要让全树所有点,到这条路径的最大距离最小
由于本题所有的边权均为非负,那么直径的端点显然只能是叶子节点,否则还能再长。
整个树可以抽象如下:
1
到2
是一条直径,3
到4
是一条直径,5
和6
是直径分叉点,ABCDEF均为子树。
结合上述两条性质,选哪条直径对最大距离压根没有影响....
因为1 - 5
和3 - 5
距离完全相同,2 - 6
和4 - 6
距离也完全相同,其余子树都接在直径们的公共路径上。
所以直接两次BFS求出任意一条直径即可拿来做文章。

二分
最大值最小
显然符合二分的性质,考虑验证条件。
设最大距离为mid
,如果每个点到所选路径的最大距离都不会超过mid
,验证成功。
设直径的两端点分别为p
和q
,令它俩各向内收缩mid
距离,分别到达点u
和v
,作图所示。

如果
u - v
路径长度大于s
,说明不满足题意。子树
D
在p - u
路径上,子树E
在q - v
路径上,那么
D
或E
的任意点到u - v
的路径长度都不可能大于mid
,否则D 或 E - u - v - q
能成为新的直径。换句话说,
p
和q
尽量向内收缩的过程中,顺带还能确保所经路径上的其他子树的最大距离不会超过mid
!所以,如果
u > v
,说明两侧子树到直径的任意子路径的最大长度都不会超过mid
如果
u < v
且u - v
长度小于s
,说明u - v
这一段路径的子树的最大长度还需我们验证。(根据第2条,
p - u
和q - v
两条路径中的子树的最大长度必小于mid
,无须验证)我们把直径上的所有点都设置为
已访问
,然后令u - v
这条路径上的所有点执行dfs求该点能到的最远距离,这样就能找到图上A、B、C等子树到
u - v
的最远距离了。
1 |
|
单调队列与暴力
抛开二分,我们直接考虑最大距离最小的情况。
当i
、j
两个游标在直径上移动时,可以发现,当前的路径最大值取决于以下式子:
max(
p
到游标i
的距离,i
到j
路径中子树的最大距离,q
到游标j
的距离)

在固定i
的情况下,j
越大,q
到j
的距离肯定更小,所以有两种办法:
i
与j
维护一个单调队列,维护i
到j
之间子树的最大距离;只要
i
到j
的距离不超过s
,j
就一直向右扩张(贪心思路),在过程中比较上述式子。求最大值的运算具有结合律和分配律,两个游标一定会经过直径上的所有子树;
那倒不如直接暴力求出所有子树的最大距离,是个定值,记为
mx_d
;然后
i
、j
俩游标正常移动,直接比较下述式子即可:max(
p
到游标i
的距离,mx_d
,q
到游标j
的距离)
单调队列的写法
1 |
|
暴力的写法
1 |
|