1578 例题4 战略游戏(LOJ10156 LUOGU2016 普及/提高-) 最小点覆盖 树的最大独立集 树形DP

总目录

在线测评地址(ybt)

在线测评地址(LOJ)

在线测评地址(LUOGU)

该题比较好懂,样例作图如下:

 但如何处理呢?没有了思路。难道是全新的算法。看了数据范围,算法的时间复杂度是O(n^2).

树的最大独立集。

以下面稍复杂的例子来研究该题。

 对应的输入输出数据:

输入:
7
0 1 1
1 1 2
2 2 3 4
3 1 5
4 1 6
5 0
6 0
输出:
3

树形结构!!!

因为是一棵树,所以对于每个节点,我们都把它当成根节点处理→树形dp!!!

注意,某个士兵在一个结点上时,与该结点相连的所有边将都可以被了望到。

定义状态dp[u][0/1]表示u这个节点不放/放士兵

根据题意,如果当前节点不放置士兵,那么它的子节点必须全部放置士兵(想到难),因为要满足士兵可以看到所有的边,所以

dp[u][0]+=dp[to][1]

其中to是u的子节点

如果当前节点放置士兵,它的子节点选不选已经不重要了(因为树形dp自下而上,上面的节点不需要考虑),所以

dp[u][1]+=min(dp[to][0],dp[to][1])   (极难想到)

数据运行过程

f[5][0]=0,f[5][1]=1
f[3][0]+=f[5][1],即f[3][0]=1
f[3][1]=1+min(f[5][0],f[5][1])=1+0=1
f[2][0]+=f[3][1],即f[2][0]=1

f[6][0]=0,f[6][1]=1
f[4][0]+=f[6][1],即f[4][0]=1
f[4][1]=1+min(f[6][0],f[6][1])=1+0=1
f[2][0]+=f[4][1],即f[2][0]=2

f[2][1]=1+min(f[3][0],f[3][1])+min(f[4][0],f[4][1])=1+1+1=3

f[1][0]+=f[2][1],即f[1][0]=3
f[1][1]=1+min(f[2][0],f[2][1])=1+2=3

f[0][0]+=f[1][0],即f[0][0]=3
f[0][1]=1+min(f[1][0],f[1][1])=1+3=4

min(f[0][0],f[0][1])=3

ybt

通过

测试点结果内存时间
测试点1答案正确644KB3MS
测试点2答案正确664KB2MS
测试点3答案正确772KB2MS
测试点4答案正确660KB2MS
测试点5答案正确616KB1MS

LOJ

LUOGU

 AC代码:

#include <bits/stdc++.h>
#define maxn 1510
using namespace std;
struct node{
	int to,next;
}e[maxn<<1];
int head[maxn],tot,n;
int f[maxn][2];
void add(int u,int v){
	tot++,e[tot].to=v,e[tot].next=head[u],head[u]=tot;
}
void init(){
	int i,k,u,v,j;
	scanf("%d",&n);
	for(i=1;i<=n;i++){
		scanf("%d%d",&u,&k);
		for(j=1;j<=k;j++){
			scanf("%d",&v);
			add(u,v),add(v,u);//无向图 
		}
		f[u][1]=1; 
	}
	
}
void dfs(int u,int fa){
	int i,j,k,v;
	for(i=head[u];i;i=e[i].next){
		v=e[i].to;
		if(v==fa)continue;
		dfs(v,u);
		f[u][0]+=f[v][1];
		f[u][1]+=min(f[v][1],f[v][0]);
	}
}
int main(){
	init();
	dfs(0,-1);
	printf("%d\n",min(f[0][1],f[0][0]));
	return 0;
} 

 该题收获:

若没接触过,该题的难度远不止普及/提高-。

学习了 最小点覆盖树的最大独立集的计算,

最大的收获,是模拟数据过程,真实的体验到了数据的流动。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值