警位安排-树形DP题解

原题链接:Link

题目描述

树形 DP 的典型例题,是状态与父亲有关的 DP。

思路分析

这类 DP 最重要的是状态设计,可以有两种思路:

  1. 设计时只考虑自己和子树,此时自己这个点可以不满足,让父亲来满足,但是子树要全部满足。
  2. 设计时同时考虑自己和父亲,相当于预判父亲的状态,此时父亲的转移要根据儿子的预判来。

网络上一般都是第二种思路,写的比较好的是这篇,就不再重复了。

第一种思路如下:定义 \(f_{i,a,b}(a,b\in \{0,1\})\) 表示第 \(i\) 个点是否放了警卫(\(a\)),是否被监视(\(b\))。那么有:

\[ \begin{aligned} f_{u,0,0}&=\sum_{v \in \operatorname{son}(u)}{f_{v,0,1}}\\ f_{u,0,1}&=\sum_{v \in \operatorname{son}(u)}{\min(f_{v,1,1},f_{v,0,1})}\text{(至少有一个}f_{v,1,1}\text{)}\\ f_{u,1,1}&=\sum_{v \in \operatorname{son}(u)}{\min(f_{v,1,1},f_{v,0,1},f_{v,0,0})} \end{aligned} \]

按照这样写会 WA,是因为边界有小问题:对于叶子节点 \(u\),它没有儿子,所以 \(f_{u,0,1}\) 是不可能出现的,应该赋值成无穷大。注意无穷大的取值不能累加后爆 int

AC代码