对于要求咱们统计树上符合条件的路径信息的问题,咱们通常能够采用两种方法来实现,一种是树上DP,一种就是点分治。点分治更加的简洁暴力,而树上DP每每会带来至关复杂的状态转移方程,甚至咱们没法推出状态转移方程。算法
点分治的核心思想就是枚举每个顶点并统计通过该顶点的全部路径信息,而这一过程是经过重构树来实现的,而且要令重构的树拥有尽量小的深度以得到更优的性能,换言之,尽量平衡。因为树是双向无环连通图,对于图中的任意顶点,咱们都可以将其做为树根,从而将图转换为一株树。那么应该选择哪一个结点呢?咱们选择树的重心做为根结点。所谓的树的重心就是指这样的一个结点x,全部与其直接相连的子树的大小(其内包含的结点数目)均不超过整株树大小的1/2,很显然一株树可能存在多个重心,好比只有两个结点的时候,两个结点都可以做为重心。性能
而对于点分治,咱们接受一株树,并负责从中找到树的重心,处理全部通过重心的路径,以后将重心从树中移除,此时树散落为多株规模更小的树,为这些树递归调用点分治的流程,这样咱们就处理了全部可能的路径(由于一条路径必然至少通过一个顶点,而对于任意顶点,咱们都处理了通过它的路径,因此咱们处理了全部的路径)。因为寻找重心和处理通过重心的路径这一任务的时间复杂度为线性的,即若是树的大小为m,则时间复杂度为O(m)。而每一层次的递归调用,所涉及的全部子树的大小和始终不超过O(n),n为原始图的大小,所以每一层次的时间复杂度均为O(n),最终的时间复杂度如分治算法同样取决于递归的层次。而因为移除重心后,全部的子树大小最大为原来的一半,而递归终止于树的大小为1的时候,所以递归的层次能够很容易得出不超过log2(n),总的时间复杂度对应的为O(nlog2(n))。递归
下面说一下重心的其它性质:重构
性质1:若是一个结点是树的重心,则其下最大的子树的大小必然最小。方法
证实:假设x是一个含n个结点的树的重心,对于任意不一样于x的结点y。咱们发现y必然存在与x下的某株以z为根的子树中,而这意味着当以y为根结点时,以x为根的子树的大小T'(x)为整株树的大小n减去以z为根的子树大小|T(z)|,而因为x是重心,故T(z)<=n/2,故T'(x)>=n/2,即y的最大子树的大小至少为T'(x)=n/2,所以x的最大的子树的大小必然最小。统计
性质2:若是一株含n个结点的树有多个重心,则每一个重心的最大子树的大小均为n/2。移动
证实:由性质1的证实能够直接得出。时间
性质3:设树含n个结点,若u是树的重心,而v是不一样于u的树上的结点,那么向以v为根的子树中追加新的结点,树的重心将沿着从u到v的简单路径移动最多一个结点。递归调用
证实:追加一个结点后,树的大小变成了n+1,若是u的全部子树大小依旧保证小于(n+1)/2,那么u将始终是树的重心。不然,若u的某个子树大小超过了(n+1)/2,那么确定是由包含v的子树的大小增大致使的,并且很容易发现这株子树在没有扩增前的大小应该为n/2。咱们将重心从u向v移动一个单位后,此时其全部的子树大小均保证不超过(n+1)/2(此时T'(u)=n-n/2<=(n+1)/2)。枚举
性质4:将两株分别以a与b为重心的树A、B经过一条边(u,v)链接起来,那么新的重心必然处于a到b的简单路径上。
证实:不妨设新的重心落在A上,那么这等价于向A中结点u所表明的子树上不断追加新的结点,由性质3能够保证A的重心不断沿着A与结点u之间的路径不断移动。而前提已经说明了重心始终落在A上,所以新的重心必然落在A与u之间。而对应的若是新的重心落在B上,那么新的重心必然处于B与v的简单路径上,不管哪一种状况,都能保证新的重心必定处于a与b的路径上。
性质5:一株树的重心必然存在。
证实:当树的大小为1时,显然成立,而创建一株树的过程能够表示为向本来只有一个结点的树追加新的结点,利用性质3提到的算法,沿着某条路径移动最多一个结点,便可获得新的重心。而但全部顶点加入完成后,重心也得以确认。