Live2D

战略游戏题解

   这道题一看就是一道树形dp的题目

   我们首先设f[i][1]表示第i个点选择,f[i][0]表示不选。

   由此可以得出状态转移方程

   当第i个点不放时,它的儿子必须放,所以f[i][0]+=f[to][1] to为i的子节点。

   当第i个点放时,它的儿子可以也可以不放,我们取最小值f[i][1]+=min(f[to][0],f[to][1]) to为i的子节点。

#include<bits/stdc++.h>
int n,x,y,k,tot,head[1501],f[1501][2];
struct jhh
{
    int to,next;
}a[3001];
int min(int x,int y)
{
    if(x<y)
        return x;
    return y;
}
void add(int x,int y)
{
    ++tot;
    a[tot].to=y;
    a[tot].next=head[x];
    head[x]=tot;
}
void dfs(int x,int v)
{
    f[x][1]=1;
    f[x][0]=0;
    if(head[x]==0) f[x][0]=9999999;
    for(int i=head[x];i;i=a[i].next)
    { 
     int y=a[i].to;
        if(y!=v)
        {
            dfs(y,x);
            f[x][1]+=min(f[y][1],f[y][0]);
            f[x][0]+=f[y][1];
        }
    }   
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&x,&k);x++;
        for(int j=1;j<=k;j++)
        {
            scanf("%d",&y);y++;
            add(x,y);
            add(y,x);
        }
    }
    dfs(1,0);
    printf("%d",min(f[1][1],f[1][0]));
} 

 

posted @ 2019-07-19 09:39  'Jack'  阅读(132)  评论(0编辑  收藏  举报