P2016 战略游戏

  • P2016 战略游戏

    树形 DP。

    设计状态 f ( i , 0 / 1 ) f(i,0/1) f(i,0/1) 表示选或不选 i i i 节点,覆盖 i i i 及其子树的最小花费。

    状态转移:
    { f ( i , 0 ) = f ( i , 0 ) + f ( s o n i , 1 ) f ( i , 1 ) = f ( i , 1 ) + min ⁡ ( f ( s o n i , 0 ) , f ( s o n i , 1 ) ) \begin{cases} f(i,0)=f(i,0)+f(son_i,1)\\ f(i,1)=f(i,1)+\min(f(son_i,0),f(son_i,1)) \end{cases} {f(i,0)=f(i,0)+f(soni,1)f(i,1)=f(i,1)+min(f(soni,0),f(soni,1))
    注意看清题目中节点编号从 0 0 0 开始。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn=3005;
    struct edge{int to,nxt;}e[maxn];
    int head[maxn],cnt,f[maxn][2];
    
    void add(int x,int y){e[++cnt]={y,head[x]},head[x]=cnt;}
    
    void dfs(int x,int fa)
    {
    	f[x][0]=0,f[x][1]=1;
    	for(int i=head[x];i;i=e[i].nxt)
    	{
    		if(e[i].to==fa) continue;
    		dfs(e[i].to,x);
    		f[x][0]+=f[e[i].to][1],f[x][1]+=min(f[e[i].to][0],f[e[i].to][1]);
    	}
    }
    
    int main()
    {
    	int n;cin>>n;
    	for(int i=1;i<=n;i++)
    	{
    		int ii,k,u;cin>>ii>>k;
    		while(k--) cin>>u,add(ii+1,u+1),add(u+1,ii+1); 
    	}
    	dfs(1,0);
    	cout<<min(f[1][0],f[1][1]);
    	return 0;
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值