- 传统题 1000ms 512MiB
-
说明
Bob 喜欢玩电脑游戏,特别是战略游戏。但是他经常无法找到快速玩过游戏的方法。现在他有个问题。 现在他有座古城堡,古城堡的路形成一棵树。他要在这棵树的节点上放置最少数目的士兵,使得这些士兵能够瞭望到所有的路。 注意:某个士兵在一个节点上时,与该节点相连的所有边都将能被瞭望到。 请你编一个程序,给定一棵树,帮 Bob 计算出他最少要放置的士兵数。
输入格式
输入数据表示一棵树,描述如下。 第一行一个数 N ,表示树中节点的数目。 第二到第 N+1 行,每行描述每个节点信息,依次为该节点编号 i,数值 k,k 表示后面有 k 条边与节点 i 相连,接下来 k 个数,分别是每条边的所连节点编号
,
,⋯,
。 对于一个有 N 个节点的树,节点标号在 0 到 N−1 之间,且在输入文件中每条边仅出现一次。
输出格式
输出仅包含一个数,为所求的最少士兵数。
样例
输入数据 1
4 0 1 1 1 2 2 3 2 0 3 0
输出数据 1
1
提示
数据范围:对于 100%的数据,有0<N≤1500。 -
#include<bits/stdc++.h> using namespace std; int f[10005][2],v[10005],in[10005],n,k,l,head[10005],to[10005],ne[10005],tot; void add(int u, int v) { ++tot; to[tot] = v; ne[tot] = head[u]; head[u] = tot; } void dfs(int u,int fa) { f[u][0]=0; f[u][1]=1; int vv; for(int i=head[u];i;i=ne[i]) { vv=to[i]; if(vv==fa)continue; dfs(vv,u); f[u][0]+=f[vv][1]; f[u][1]+=min(f[vv][1],f[vv][0]); } } int main(){ scanf("%d",&n); int a,b,c; for(int i=1;i<=n;i++) { scanf("%d%d",&a,&b); for(int i=1;i<=b;i++) { scanf("%d",&c); add(a,c);add(c,a); } } dfs(0,-1); cout<<min(f[0][0],f[0][1]); return 0; }
#B. 「一本通 5.2 例 4」战略游戏(树的最优独立集)
最新推荐文章于 2024-07-01 01:04:23 发布
![](https://img-home.csdnimg.cn/images/20240611030827.png)