20ZR暑期集训 树形 dp

Link

POJ1463 Strategic game 树的最小覆盖集

每一条边的两个端点至少需要选一个点,求最少点数,即为树的最小覆盖集。

树形 dp 入门题,设 f x , 0 f_{x,0} fx,0 为以 x x x 为根的子树不选 x x x 的最少点数, f x , 1 f_{x,1} fx,1 为选 i i i 的最少点数。

f x , 1 = ∑ i ∈ s o n min ⁡ { f i , 0 , f i , 1 } + 1 f_{x,1} = \sum_{i \in son} \min \{ f_{i,0},f_{i,1} \} + 1 fx,1=isonmin{fi,0,fi,1}+1

f x , 0 = ∑ i ∈ s o n f i , 1 f_{x,0} = \sum_{i \in son} f_{i,1} fx,0=isonfi,1

a n s = min ⁡ { f r o o t , 0 , f r o o t , 1 } ans = \min \{ f_{root,0}, f_{root,1} \} ans=min{froot,0,froot,1}

POJ 3659 Cell Phone Network (树的最小支配集)

选择了一个点后,与自己相邻的点被覆盖,求覆盖所有点集的最少点数,即为树的最小支配集。

f x , 0 f_{x,0} fx,0 为选 x x x x x x 的子树都覆盖了, f x , 1 f_{x,1} fx,1 为不选 x x x x x x 的儿子覆盖了 x x x f x , 2 f_{x,2} fx,2 为不选 x x x x x x 的父亲覆盖了 x x x。然后确定转移方程

对于 f x , 0 f_{x,0} fx,0 f x , 2 f_{x,2} fx,2 的转移是显而易见的

f x , 0 = 1 + ∑ i ∈ s o n min ⁡ { f i , 0 , f i , 1 , f i , 2 } + 1 f_{x,0} = 1 + \sum_{i \in son} \min \{ f_{i,0}, f_{i,1}, f_{i,2} \}+ 1 fx,0=1+isonmin{fi,0,fi,1,fi,2}+1

f x , 2 = ∑ i ∈ s o n f i , 1 f_{x,2} = \sum_{i \in son} f_{i,1} fx,2=isonfi,1

对于 f x , 1 f_{x,1} fx,1 稍微复杂点,因为至少要有一个儿子选了 f x , 0 f_{x,0} fx,0 所以定义 i n c inc inc,当选了至少一个儿子的 f i , 0 f_{i,0} fi,0 i n c = 0 inc = 0 inc=0。否则 i n c inc inc 选择一个最小的 f i , 0 f_{i,0} fi,0,即 i n c = min ⁡ { f i ∈ s o n , 0 − f i , 1 } inc = \min \{f_{i \in son,0} - f_{i,1}\} inc=min{fison,0fi,1}。那么它的转移方程为

f x , 1 = ∑ i ∈ s o n min ⁡ { f i , 0 − f i , 1 } f_{x,1} = \sum_{i \in son} \min \{ f_{i,0} - f_{i,1} \} fx,1=isonmin{fi,0fi,1}

POJ 3107 Godfather (树的重心)

树的重心为删掉这个点后将树分成几个部分中点的个数最大值最小。树最多有两个重心。

令一个点为根,维护 s z x sz_x szx 为以 x x x 为子树的大小,分成两种:x 下面的子树与 x 上面的部分。

void dfs(int x, int fa){
    sz[x] = 1;
    int maxn = 0;
    for (int i = hd[x]; i; i = e[i].nxt){
        int y = e[i].to; 
        if(y != fa){
            dfs(y,x);
            sz[x] += sz[y];
            maxn = max(maxn, sz[y]);
        } 
    }
    maxn = max(maxn, n - sz[x]);
    ans[x] = maxn;
    minn = min(maxn, minn);
}

POJ 2631 Roads in the North (树的直径)

树的直径为树的最长路。

树的直径求法一:随便找一个点,然后 bfs 找到离任意一个点最远的点 u u u,再从最远的点 u u u 找到最远的点 v v v,那么 ( u , v ) (u, v) (u,v) 为树的直径。

树的直接求法二:树形dp。对于每个点维护 d o w n 1 x down1_x down1x(经过不同儿子向下到叶子节点的最长路) 和 d o w n 2 x down2_x down2x(经过不同儿子向下到叶子节点的次长路)。枚举一个点 i i i,最后的结果为 m a x { d o w n 1 i + d o w n 2 i } max \{ down1_i + down2_i\} max{down1i+down2i}。不难证明对于一个节点,在只继承它的儿子最大值的前提下,它到叶子结点距离的最大值和次大致所经过的路径一定是不一样的。

拓展:定义 r x r_x rx 为离 x x x 最远的点 与 x x x 的距离。树的中心为满足 r x r_x rx 最小的点的 x x x。树的中心为直径的中点。所有的直径都经过中心。

HDU 2196 Computer (树的最远距离)

给出一棵树, 问从每个点出发所能到达的最远距离。

f x , 0 f_{x,0} fx,0 为以 x x x 为根的子树中离 x x x 的最远距离, f x , 1 f_{x,1} fx,1 为以 x x x 为根的子树中离 x x x 的次远距离,这个东西很好转移,我们从下往上进行树形 dp,对于儿子传递的信息,先与它的最远距离比较,不行的话再与次元距离比较。

刚才的两个状态是最远路径一开始是往下走的,还有一开始往上走的,中途可能拐下来的。设 f x , 2 f_{x,2} fx,2 x x x 一开始往上走的最远距离。从上向下进行树形 dp,转移方程如下,约定 ∉ \notin / ∈ \in 含义为不经过和经过, z z z ( x , y ) (x,y) (x,y) 的长。

f y ∈ s o n , 2 = max ⁡ { f x , 0 + z , f x , 2 + z } ( f x , 0 ∉ y ) f_{y \in son,2} = \max \{ f_{x,0} + z, f_{x,2} + z \} \quad (f_{x,0} \notin y) fyson,2=max{fx,0+z,fx,2+z}(fx,0/y)

f y ∈ s o n , 2 = max ⁡ { f x , 1 + z , f x , 2 + z } f_{y \in son, 2} = \max \{ f_{x,1} + z, f_{x,2} + z \} fyson,2=max{fx,1+z,fx,2+z}

a n s x = max ⁡ { f x , 0 , f x , 2 } ans_x = \max \{ f_{x,0}, f_{x,2} \} ansx=max{fx,0,fx,2}

拓展:如果题目求的是经过每个点的最长链怎么写?易知经过 x x x 的最长链为

a n s x = max ⁡ { f x , 0 + f x , 2 , f x , 0 + f x , 1 } ans_x = \max \{f_{x,0} + f_{x,2}, f_{x,0} + f_{x,1}\} ansx=max{fx,0+fx,2,fx,0+fx,1}

HDU 6035 Colorful Tree

给定一棵 n n n 个点的树,每个点都有颜色 c i c_i ci。定义两点间距离为路径上不同颜色的数量。求两两点对距离和。

来学习一下套路。将问题转换成每个颜色对答案的贡献,即为有多少条路径经过它,求个补集是有多少条路径不经过它。所以枚举颜色并标记,进行树形 dp 即可。也可以重新构图,对每个联通树进行 dfs。

一棵大小为 n n n 的树有 n × ( n − 1 ) 2 \frac{n \times (n-1)}{2} 2n×(n1) 条路径。

CF1101D GCD Counting

给定一棵有点权的树,求树上满足点权 gcd ⁡ ≠ 1 \gcd \not=1 gcd=1 的最长路径。

最长路径有两个考虑方式,断点和 lca。端点需要记录最长链,次长链,和往上的最长链即为到根的路径。lca 需要记录向下的两个最长链。

扯回来,gcd 怎么记录在状态中,记录每个 gcd 是不合理的。既然题说了 gcd ⁡ ≠ 1 \gcd \not = 1 gcd=1 就有贡献,就记录质因子即可。

1 × 3 × 5 × 7 × 11 × 13 × 17 = 255255 > 2 × 1 0 5 1 \times 3 \times 5\times7\times11\times13\times17 = 255255 > 2\times 10^5 1×3×5×7×11×13×17=255255>2×105

UVA10859 Placing Lampposts

给定一个 n n n m m m 边的无向无环图,在尽可能少的节点上放灯,使得所有边与灯相邻。并在灯数最少的前提下,被照亮的边应尽可能多。求最少灯数,被两个灯和一个灯照亮的边数。

无向无环图是一个森林,只考虑一棵树。设 f i , 0 / 1 f_{i,0/1} fi,0/1 为第 i i i 个点不放和放灯的最少灯数。但要求在灯树最少的前提下被照亮的边尽可能多,所以把放灯的花费设为一个极大值。把儿子放灯了父亲也放灯的花费设为一,求最小花费即可。

树形依赖背包

P3177 树上染色

给定一个 n n n 个点的树,有边权。给定 k k k,将 k k k 个点染成黑色,其它染成白色。收益是所有黑点两两之间和白点两两之间的距离和。求最大收益。

f i , j f_{i,j} fi,j 为在子树 i i i 中选 j j j 个点对答案的贡献。

考虑黑白间是独立的,对于一棵子树,它的一个儿子中的节点想要走到另一个儿子,条件是另一个儿子的子树中有与它同色的。那么将其它子树看成一个整体,在结合父亲的信息,可以求出儿子经过连向父亲的边多少次。

可以发现是一个树形依赖背包。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值