#sXDPybttg050205. 1579:【例 5】皇宫看守

1579:【例 5】皇宫看守

好的,我将这道题整理为清晰的题面格式,并补充样例解释、数据范围与时空限制:


题目描述

太平王世子事件后,陆小凤成了皇上特聘的御前一品侍卫。

皇宫以午门为起点,直到后宫嫔妃们的寝宫,呈一棵树的形状,某些宫殿间可以互相望见。大内保卫森严,三步一岗,五步一哨,每个宫殿都要有人全天候看守,在不同的宫殿安排看守所需的费用不同。

可是陆小凤手上的经费不足,无论如何也没法在每个宫殿都安置留守侍卫。

帮助陆小凤布置侍卫,在看守全部宫殿的前提下,使得花费的经费最少。

注意:这里的“看守全部宫殿”意味着每个宫殿要么有侍卫,要么被其他宫殿的侍卫望见(即每个节点要么自己放侍卫,要么被父节点或子节点的侍卫覆盖)。


输入格式

输入中数据描述一棵树,描述如下:

  • 第一行一个整数 nn,表示树中结点的数目;
  • 接下来 nn 行,每行描述一个宫殿结点信息:
    1. 该宫殿结点标号 ii0<in0 < i \le n);
    2. 在该宫殿安置侍卫所需的经费 kk
    3. 该结点的儿子数 mm
    4. 接下来 mm 个整数 r1,r2,,rmr_1, r_2, \dots, r_m,分别是这个节点的 mm 个儿子的标号。

对于一个 nn 个结点的树,结点标号在 11nn 之间,且标号不重复。


输出格式

输出一行一个整数,表示最少的经费。


样例

样例输入

6
1 30 3 2 3 4
2 16 2 5 6
3 5 0
4 4 0
5 11 0
6 5 0

样例输出

25

样例解释

树的结构:

  • 节点1(经费30)有3个儿子:2,3,4
  • 节点2(经费16)有2个儿子:5,6
  • 节点3(经费5)无儿子
  • 节点4(经费4)无儿子
  • 节点5(经费11)无儿子
  • 节点6(经费5)无儿子

图示(原题有图):

      1
   /  |  \
  2   3   4
 / \
5   6

要求每个节点要么自己放侍卫,要么被相邻节点放侍卫覆盖。

最优方案:

  • 在节点2放侍卫(经费16),覆盖节点1,2,5,6;
  • 在节点3放侍卫(经费5),覆盖节点1,3;
  • 在节点4放侍卫(经费4),覆盖节点1,4。

总费用 16 + 5 + 4 = 25。


数据范围

对于 100%100\% 的数据,0<n15000 < n \le 1500


时空限制

  • 时间:1000 ms1000 \text{ ms}
  • 内存:524288 KB524288 \text{ KB}

提示
此题为 树的最小权点覆盖(带权)树形DP(状态机) 问题。

最小点覆盖 不同,这里每个点可以选择自己覆盖、被父亲覆盖或被儿子覆盖。
因此每个节点有三种状态:

  • dp[u][0]dp[u][0]uu 被父节点覆盖时,以 uu 为根的子树的最小费用;
  • dp[u][1]dp[u][1]uu 被自己覆盖时,以 uu 为根的子树的最小费用;
  • dp[u][2]dp[u][2]uu 被某个子节点覆盖时,以 uu 为根的子树的最小费用。

转移方程(son(u)son(u)uu 的子节点集合):

  1. dp[u][0]dp[u][0]uu 被父节点覆盖,则 uu 自己不放侍卫,但子节点必须被自己或它们的子节点覆盖(不能依赖 uu),所以:$$dp[u][0] = \sum_{v \in son(u)} \min(dp[v][1], dp[v][2])$$
  2. dp[u][1]dp[u][1]uu 自己放侍卫,费用加上 cost[u]cost[u],子节点可被 uu 覆盖(即子节点可以处于被父节点覆盖状态 dp[v][0]dp[v][0]),也可自己或被子节点覆盖:$$dp[u][1] = cost[u] + \sum_{v \in son(u)} \min(dp[v][0], dp[v][1], dp[v][2])$$
  3. dp[u][2]dp[u][2]uu 被子节点覆盖,即至少有一个子节点放侍卫(dp[v][1]dp[v][1]),其他子节点可以处于 dp[v][0]dp[v][0]dp[v][2]dp[v][2]dp[v][2]dp[v][2] 要求被它的子节点覆盖,这里处理需要保证 uu 被覆盖。
    更简便的方法:$dp[u][2] = \min\limits_{v \in son(u)} \{ dp[v][1] + \sum_{w \in son(u), w \ne v} \min(dp[w][0], dp[w][1], dp[w][2]) \}$
    或者用 $dp[u][2] = \min\{ dp[u][0] - \min(dp[v][1], dp[v][2]) + dp[v][1] \}$ 枚举 vv

最终根节点(比如1)不能处于 dp[root][0]dp[root][0](因为没有父节点),所以答案为 min(dp[root][1],dp[root][2])\min(dp[root][1], dp[root][2])

复杂度 O(n)O(n)