POJ 1463 Strategic game

状态表示:
对于任意一条边,要么在父亲放士兵,要么在儿子放士兵。
\(f(u,0)\):以\(u\)为根的子树在\(u\)上不放置的士兵的情况下,最少所需的士兵数目。
\(f(u,1)\):以\(u\)为根的子树在\(u\)上放置的士兵的情况下,最少所需的士兵数目。

状态转移:
\(u\)上放置士兵,\(u\)的儿子们可放可不放。

\[f(u,1)=1+\sum_{j \in Son(u)} min(f(j,0),f(j,1)) \]

\(u\)上不放置士兵,\(u\)的儿子们必须放。

\[f(u,0)=\sum_{j \in Son(u)} f(j,1) \]

const int N=1510;
vector<int> g[N];
int f[N][2];
int n;

void dfs(int u,int fa)
{
    f[u][0]=0;
    f[u][1]=1;

    for(int i=0;i<g[u].size();i++)
    {
        int j=g[u][i];
        if(j == fa) continue;
        dfs(j,u);
        f[u][0]+=f[j][1];
        f[u][1]+=min(f[j][0],f[j][1]);
    }
}

int main()
{
    while(cin>>n && n)
    {
        for(int i=0;i<n;i++) g[i].clear();

        for(int i=0;i<n;i++)
        {
            int id,m;
            scanf("%d:(%d)",&id,&m);
            while(m--)
            {
                int x;
                scanf("%d",&x);
                g[id].pb(x);
                g[x].pb(id);
            }
        }

        dfs(0,-1);
        
        cout<<min(f[0][0],f[0][1])<<endl;
    }
    //system("pause");
    return 0;
}
posted @ 2021-04-09 09:25  Dazzling!  阅读(28)  评论(0编辑  收藏  举报