HDU 1054 Strategic Game (树形DP)

来源:互联网 发布:cdn加速 知乎 编辑:程序博客网 时间:2024/04/30 12:39

dp[0][i]表示在i点上不放置一个士兵时的最小值,dp[1][i]表示在i点上放置一个士兵时的最小值。那么状态转移方程:

dp[0][u]=sum(dp[1][v]),dp[1][v]=1+sum(min(dp[1][v],dp[0][v]);

代码如下:

#include <iostream>#include <string.h>#include <math.h>#include <queue>#include <algorithm>#include <stdlib.h>#include <map>#include <set>#include <stdio.h>using namespace std;#define LL __int64#define pi acos(-1.0)const int mod=100000000;const int INF=0x3f3f3f3f;const double eqs=1e-8;int dp[3][3000], head[3000], cnt;struct node{    int u, v, next;}edge[100000];void add(int u, int v){    edge[cnt].v=v;    edge[cnt].next=head[u];    head[u]=cnt++;}void dfs(int u, int fa){    dp[1][u]=1;    dp[0][u]=0;    for(int i=head[u];i+1;i=edge[i].next){        int v=edge[i].v;        if(v==fa) continue ;        dfs(v,u);        dp[0][u]+=dp[1][v];        dp[1][u]+=min(dp[1][v],dp[0][v]);    }}void init(){    memset(head,-1,sizeof(head));    cnt=0;}int main(){    int n, i, j, m, u, v;    while(scanf("%d",&n)!=EOF){            init();        for(i=0;i<n;i++){            scanf("%d:(%d)",&u,&m);            while(m--){                scanf("%d",&v);                add(u,v);                add(v,u);            }        }        dfs(0,-1);        printf("%d\n",min(dp[0][0],dp[1][0]));    }    return 0;}


1 0