Strategic game POJ

题目大意:

  给你一棵树 选一个点既选择了与其相邻的边,求选择最少的点包含全部的边;

思路:入门题:对于每一个节点,选与不选2个状态,如果不选,那么他的子节点必须都要选

dp[u][0] 不选u

dp[u][1] 选u;

  

#include<cstdio>
#include<cstring>
#include<vector>
#include<iostream>

using namespace std;

const int maxn=1e5+10;

#define mem(a,b) memset(a,b,sizeof(a))

vector<int>q[maxn];
int dp[maxn][3];

void init(int n)
{
    for(int i=0;i<n;i++)
        q[i].clear();
    mem(dp,0);
}

void creat_edge(int u,int v)
{
    q[u].push_back(v);
}

void dfs(int u,int fa)
{
    int t=q[u].size();
    for(int i=0;i<t;i++)
    {

        int v=q[u][i];
        if(v==fa) continue;
        dfs(v,u);
        dp[u][0]+=dp[v][1];
        dp[u][1]+=min(dp[v][0],dp[v][1]);
    }
    dp[u][1]+=1;

}



int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        init(n);
        int u,mub;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&u);
            scanf(":(%d)",&mub);

            //cin>>u;
            //cout<<u<<" ";
            //cin>>ch>>ch>>mub>>ch;
            //cout<<mub<<endl;
            for(int i=1;i<=mub;i++)
            {
                int v;
                scanf("%d",&v);
                creat_edge(u,v);
                creat_edge(v,u);
            }
        }
        dfs(0,-1);
        printf("%d
",min(dp[0][0],dp[0][1]));
        //cout<<min(dp[0][0],dp[0][1])<<endl;
    }

    return 0;
}
原文地址:https://www.cnblogs.com/minun/p/10821995.html