#sXDPybttg050204. 1578:【例 4】战略游戏

1578:【例 4】战略游戏

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


题目描述

Bob 喜欢玩电脑游戏,特别是战略游戏。但是他经常无法找到快速玩过游戏的方法。现在他有个问题。

现在他有座古城堡,古城堡的路形成一棵树。他要在这棵树的节点上放置最少数目的士兵,使得这些士兵能够瞭望到所有的路。

注意:某个士兵在一个节点上时,与该节点相连的所有边都将能被瞭望到。

请你编一个程序,给定一棵树,帮 Bob 计算出他最少要放置的士兵数。


输入格式

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

  • 第一行一个整数 NN,表示树中节点的数目。
  • 接下来 NN 行,每行描述一个节点信息:
    1. 第一个整数 ii,表示节点编号(从 00N1N-1);
    2. 第二个整数 kk,表示后面有 kk 条边与节点 ii 相连;
    3. 接下来 kk 个整数 r1,r2,,rkr_1, r_2, \dots, r_k,分别是每条边所连接的节点编号。

对于一个有 NN 个节点的树,节点标号在 00N1N-1 之间,且在输入文件中每条边仅出现一次。


输出格式

输出仅包含一个整数,为所求的最少士兵数。


样例

样例输入

4
0 1 1
1 2 2 3
2 0
3 0

样例输出

1

样例解释

N=4N=4,树的结构如下(根据输入):

  • 节点 0:连接节点 1
  • 节点 1:连接节点 2 和节点 3
  • 节点 2:无连接(实际上表示 k=0,即没有子节点)
  • 节点 3:无连接

因此树形结构:

0 — 1 — 2
    |
    3

实际上节点 0 与节点 1 相连,节点 1 与节点 2 和节点 3 相连。

我们需要选择一些节点放置士兵,使得每条边都被覆盖(即每条边的至少一个端点有士兵)。

这是一个 树的最小点覆盖 问题。

在节点 1 放一个士兵,可以覆盖边 (0,1)、(1,2)、(1,3),所有边都被覆盖。
所以最少士兵数为 1。


数据范围

对于 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 为根的子树所需的最少士兵数。

转移方程:

  • uu 不放置士兵,则 uu 的所有子节点 vv 必须放置士兵(否则边 (u,v)(u,v) 无法被覆盖):dp[u][0]=vson(u)dp[v][1]dp[u][0] = \sum_{v \in \text{son}(u)} dp[v][1]
  • uu 放置士兵,则子节点 vv 可放可不放,取较小值:$$dp[u][1] = 1 + \sum_{v \in \text{son}(u)} \min(dp[v][0], dp[v][1])$$

初始化:对于叶子节点,dp[u][0]=0dp[u][0]=0dp[u][1]=1dp[u][1]=1

最终答案为 min(dp[root][0],dp[root][1])\min(dp[root][0], dp[root][1]),其中 rootroot 是树的根(可以任选,比如 0)。

复杂度 O(N)O(N)