~{→看不见LaTex格式的Dalao们请刷新本页Thanks♪(・ω・)ノ←}~
(淀粉质)点分治
推荐一道模板题。
我们选择任意一个根$root$,将树变为一棵无根树。
那么我们对于树上任意两个点之间的路径必定被转化为经过$root$的路径,或是位于$root$某一棵子树中的路径。
所以我们就能够把一条路径分到几棵子树中分治求解。点分治后,每一层分别对$n$个点处理一次,递归$k$层的复杂度为$O(kn)$。
不过当树变为一条链之后,最坏的情况是当$root$取首尾节点时,有$k=n$,时间复杂度为$O(n^2)$。
那么我们选择$root$时应该怎么选择呢?
树的重心是个好的选择,它能使递归的层数减到最少。
我们记录每个点$i$到根节点$root$的距离$dis_i$,那么从$u$到$v$的路径长度为$dis_u+dis_v$。
同时设$max$_$part[i]$表示删除$i$节点后,最大的子树的大小。
树的重心节点$g$一定是$max$_$part[g]=(max$_$part[i])_{min}$。
取重心也就保证了时间复杂度稳定在$O(nlogn)$左右。
是不是比原来$O(n^2)$的算法优秀了很多呢?
Code
1 |
|