这是紫书P280~P282的读书笔记
树的最大独立集
概念:在一个无根树中选出一些互不相邻的点,使这个集合最大
定义:d[i]为以i为根的子树中最大独立集的值,s[i]表示i的儿子,gs[i]表示孙子
方程:对于i点只有两种状态选或者不选,可以看成一个01背包问题,转移只有两种:
d[i]=max(1+sum(d[j1]),sum(d[j2]));j1∈gs[i],j2∈s[i];sum是累加注意的地方:
如果对于每一个需要计算的地方我们都要找出其所有的s和gs,不容易实现,
可以选择:枚举到i点时,直接累加其fa和gf——–刷表法
树的重心
概念:删去节点i后的最大联通块的大小最小
应用:树的点分治中避免x^2的极端情况(从退化链一端出发)
定义:d[i] 以i为根的子树的大小
易得:d[i]=∑j∈s[i]d[j]+1
所以对于节点i来说,它若为重心的值即h[i]=max(d[j])+n-d[i]
求h[i]和d[i]的操作在无根树转有根时可一起完成
最远点对
DFS:
两次dfs即可,证明可用反证法
-
dp:
定义:d[i] 以i为根的子树到叶子的最长距离(不能向上)
思路:经过i点的最长路径是儿子最大值与次大值相加
所以:d[i]=maxd[j]+max2d[j]+2
-
拓展:对于一颗n个结点的无根树,求出每个结点的最远点,要求时间复杂度为O(n)
补充一下对于求树直径的dfs证明:
树的直径是树上最长的一条边
方法:任取一点u,用DFS求出其最长点v,对于v,再dfs(v),求出v的最远点w,
v–w就是直径1°:若任取的一点u在直径上,显然u的最远点v是直径的一个端点.v的另一个端点w就是直径的第二个端点
至于为什么v是直径的一个端点:我们假设存在一点x使得u-x的距离大于u-v的距离,因为u在直径上所以以x是这条直径上距离u较长一端的端点,这与v也是端点相矛盾,故v是直径的一个端点.2°:若这点u不在直径上,我们不妨设这棵树的两个端点分别为v,w,我们通过两次搜索到的是x,y点.若x,y的路径中有点与u,v重合那么回到了第一种情况是正确的.若x,y与v,w完全不相交,因为是树所以必定是一个联通块,一定有边连接在u,v和x,y构成的两个联通块中,所以直径无疑是x,y与v,w之间的最远点,所以又回到了第一种情况.
至此,所有情况讨论完毕,均成立.
如上,证毕.
回到这个问题中:
方法:两次dfs得到树的直径,然后分别从直径的两端出发,更新其最大值.
证明类似于上问 问题摸我
树的dp的一些基本东西就在这里~~
orz~~例题看我后面的博客了(^o^)