问题引入:

静态统计一棵树上符合条件路径数

前置知识:

①分治思想

②求树的重心

重心的定义:

去掉树中任意一个点,可得到多颗子树,设这这些子树的大小为a_1,a_2,...,a_n

重心就是在树中去掉之后得到的a_1,a_2,...,a_n中最大的值最小的那个点(又称质点)

重心的一个重要性质:重心的所有子树的

性质的证明:

核心思想

“分”与"治”

分:

每次选取重心为根,对树进行划分。

求重心的思路:

就是一遍dfs.枚举每个点,对于每个点求各个子树的大小,从中选出最小值当做结果,然后更新最小值.遍历完后即得到答案.


这里递归层数就为三层

治:

解决了分的问题后,我们要解决“治”的问题(确定T(n))。也就是如何快速的统计路径个数。

而对于一个根而言,树上的路径分为两种:(1)路径经过根 (2)路径不经过根,这样构成了路径的完整划分.

对于路径(1):

①在本连通分量中,找到重心,将其当作根.

②O(n)遍历一遍树找出每个点离根的距离,dis数组

③选取任意两个点的树链合并成一条路径(包括根自己),这样就把所有的路径(1)找出来了.但是有一个问题,可能这两个点在同一颗子树内,这时我们需要减去这一部分的贡献(简称容斥),等下一层再算的时候需要以它的儿子们为根再额外算一遍路径数,容斥掉这一部分的贡献就好.

对于路径(2):

首先,不管是一棵树还是一条路径,里面的任意节点都可以看成是根。

所以就算路径(2)不过之前的根,但是他总会过某一个根。

所以我们可以拿掉重心,余下来它的子树。对于每一个子树重复进行上述步骤.总会将路径(2)统计完全。


题目清单:

https://www.cnblogs.com/cjoierljl/p/9502408.html