Luogu P2458 [SDOI2006]保安站岗 解题报告
有一棵无根树有 $n$ 个点,每个点都可以被其相邻的点望到。
每个点带有一个权值,求保证所有点都可以被望到的情况下花费总代价最少。
解题思路:
树形 DP。
最开始我的想法和树上最小点覆盖的想法一样,每个点有选与不选两种状态,暴力转移。
成功拿到 10 分。
回到正题,这题和树上最小点覆盖的本质区别在于:
- 树上最小点覆盖每个点只能被父亲看见
- 本题中的每个点可以被父亲或者儿子看见
所以直接导致我们的状态不再适用。
那么怎么办呢?可以暴力直接把这种情况加进去!
同样,我们设 $f_{i,0/1/2}$ 表示第 $i$ 个点的情况:
- 如果是 0 ,表示当前点被选中
- 如果是 1 ,表示当前点是被父亲看到的,且当前点未被选中
- 如果是 2 ,表示当前点是被儿子看到的,且当前点未被选中
前两种情况的转移方程很好写,考虑可行性即可。
$$f_{x,0} = \min_{y \in son(x)}(f_{y,0,}f_{y,1},f_{y,2})$$
因为该点被选中,所以子节点怎么转移都行
$$f_{x,1} = \min_{y \in son(x)}(f_{y,0},f_{y,2})$$
因为该点没被选中,所以子节点中 $f_{y,1}$ 就不能被转移。
最后一种情况似乎大同小异:
$$f_{x,2} = \min_{y \in son(x)}(f_{y,0},f_{y,2})$$
但是,让我们考虑这样的一种情况:
在这张图中,$f_{1,2} = f_{2,2}+f_{3,2}+f_{4,2}$ ,显然不符合状态的定义, $1$ 并没有被观察到,所以我们还要暴力选择一个$f_{y,0}-f_{y,2}$差值最小的点(上图中为 $2$)才能保证正确性。
所以我们就可以写出最后一种情况的方程了:
如果有选择 $f_{y,0}$,则
$$f_{x,2} = \min_{y \in son(x)}(f_{y,0},f_{y,2})$$
如果没有,则
$$f_{x,2} = \min_{y \in son(x)}(f_{y,0},f_{y,2}) + \min_{y \in son(x)}(f_{y,0} - f_{y,2}))$$
这两个只要在代码实现时候记录下即可。
初值:$f_{x,0} = a_x,f_{x,1} = f_{x,2} = 0$
目标:$\min(f_{root,0},f_{root,2})$(根节点没有父亲,所以没有 $f_{root,1}$ 的情况)
最后,由于并没有指定根,所以读入时还要记一下入度为 0 的点当作根开始 DP。
代码:
省略头文件
1 | int n,a[N],f[N][3],deg[N]; |
Luogu P2458 [SDOI2006]保安站岗 解题报告