POJ1463 Strategic game (树形DP)


节点u不放置,其所有子节点都需要放置:节点u放置,子节点既可以放置,又可以不放置,取min。

边界条件:dp[u][0]=0,dp[u][1]=1;

求解目标:min(dp[root][0],dp[root][1]),root是树根。

#include
#include
#include
#include
using namespace std;
const int N=1510;
int val[N],dp[N][2],fa[N],n;//设置fa数组的目的是为了找根 
vector<int>E[N];

void dfs(int u){
    dp[u][0]=0;
    dp[u][1]=1;
    for(int i=0;i){
        int v=E[u][i];
        dfs(v);
        dp[u][1]+=min(dp[v][1],dp[v][0]);
        dp[u][0]+=dp[v][1];
    }
}

int main(){
    scanf("%d",&n);
        for(int i=0;i) E[i].clear();
        memset(fa,-1,sizeof(fa));
        memset(dp,0,sizeof(dp));
        for(int i=0;i){
            int a,b,m;
            scanf("%d%d",&a,&m);
            while(m--){
                scanf("%d",&b);
                E[a].push_back(b);
                fa[b]=a;
            }
        }
        int rt=0;
        while(fa[rt]!=-1) rt=fa[rt];//找根 
        dfs(rt);
        printf("%d\n",min(dp[rt][1],dp[rt][0]));
    return 0;
}
DP