简述
换根DP是一类特殊的树形DP。
在解题过程中,存在一类树上问题,要求我们求解每个节点做为根节点的时的一些数据的问题。朴素算法一般是 O ( n 2 ) O(n^2) O(n2)地进行n次dfs。遇到这种问题时,我们可以通过考察根节点转移到相邻节点时的影响,从而得出状态转移方程,进而 O ( 1 ) O(1) O(1)地转移根节点得到新的答案。最后达到将问题总的复杂度降到 O ( n ) O(n) O(n)的目的。
问题引入
给定一棵n个节点无向树(n个节点,n-1条无向边的连通图),要求选出一个节点,使得该节点做为根节点时,所有节点的深度和最大。
某个节点的深度被定义为 该节点与根节点的距离。
我们不难想到用dfs在 O ( n ) O(n) O(n)的时间内求出任一给定节点做为根节点时, 所有节点的深度和. 因此容易想到一个朴素的算法是进行n次dfs, 时间复杂度 O ( n 2 ) O(n^2) O(n2).
朴素算法是可行的, 但我们并不满足.
使用换根DP可以将时间复杂度降到 O ( n ) O(n) O(n).
问题分析
让我们钦定选定一号节点做为根节点.
让 s i z e i size_i sizei表示以第i个节点为根节点的子树大小.(一号节点做为根节点的意义下)
让 d p i dp_i dpi表示第i个节点做为根节点时的所有节点的深度和.
记节点 u u u 为节点 v v v的 (一号节点做为根节点的意义下的)父节点.
那么可以得到状态转移方程 d p v = d p u − s i z e v + ( s i z e 1 − s i z e v ) dp_v = dp_u-size_v+(size_1-size_v) dpv=dpu−sizev+(size1−size