概述
当要解决涉及树上所有链的问题时,我们迫切地需要一个算法,时间复杂度良好,且能够将树上所有的链不重不漏地列举。
将一棵具有n个节点的树,包含了总共n个的以1…n为根节点的子树。
有这样的方法,使得树上所有的链被不重不漏地列举。
统计子树中一定过树根的链,一定能保证树上所有的链不重不漏地列举。
但是有些题目中,会有这样子的链:
显然这是不符合题意的,因为会经过某些点2次。所以有时候根据题目,容斥一下。
但是怎样进行分治会使复杂度达到良好呢?
尝试每个点遍历
log
l
o
g
次,则总复杂度为
n log n
n
l
o
g
n
让每棵子树的重心成为该子树的根就好了。
换句话说,就是每棵子树,以它的重心为根遍历下去就好了。
因为重心一定能够将树分为点数差不多的两部分,其中的一部分
≤n2
≤
n
2
。
也还有这样的方法,使得树上所有的链被不重不漏地列举。
对应的,以x为根节点的子树中,将要列举的链分成2段,一段是从x的某个子树的节点y,另一段是除了这个子树外的,在w的其他子树内中的点到x。
例题
JZOJ3329
JZOJ树中点对距离