树的直径
定义:对于一颗无根树,找到两个点,使得他们之间的距离最远,这个距离就是树的直径。
求法:
- 两次bfs或dfs(O(n)):第一次以任意节点 x 为根,求出距离最远点 y,这个点一定在树的直径上(证明:树的直径求法及证明),第二次以这个点为根跑出来的最远点 z,y 与 z 的距离,就是树的直径。
- 树形 dp(O(n)) :dp[ i ]表示经过 i 点的最长链长度。
性质:
- 直径两端点一定是两个叶子节点
- 距离任意点最远的点一定是直径的一个端点,这个基于第一种求直径方法的正确性可以得出
- 对于两棵树,如果第一棵树直径两端点为(u, v) (u, v),第二棵树直径两端点为(x, y) (x, y),用一条边将两棵树连接,那么新树的直径一定是u, v, x, y, u, v, x, y, 中的两个点
题目:Tree
题解:Tree(树形dp)
学习博客:树的直径及其性质与证明
树的重心
定义:对于一颗n个节点的无根树,找到一个点,使得把树变成以该节点为根的有根树时,最大子树的节点数最小,也就是说删除这个点后最大联通块的节点数最小。
求法:
dp(O(n)):用dp[ i ]代表以i为根的子树的所有节点个数(包含i节点本身),如果要以 i 为重心的话,那么其最大子树的节点数就是max(max(dp[ j ]), n - dp[ i ]),其中 j 为 i 的孩子节点。
性质:
- 树中所有点到某个点的距离和中,到重心的距离和是最小的;如果有两个重心,那么他们的距离和一样。
- 把两个树通过一条边相连得到一个新的树,那么新的树的重心在连接原来两个树的重心的路径上。
- 把一个树添加或删除一个叶子,那么它的重心最多只移动一条边的距离。
- 以重心为根的树,则重心的所有子树的最大规模不会超过这棵树规模的一半。
- 数的重心最多只有两个,且一定相邻