ZOJ 1134 Strategic Game(树形DP)

来源:互联网 发布:王国纪元城堡升级数据 编辑:程序博客网 时间:2024/04/29 23:25

dp[i][0]表示i结点放士兵的最优值,dp[i][1]表示i结点不放士兵的最优值

因为是一棵树,所以状态转移方程:

1.dp[i][0]+=min(dp[v][0],dp[v][1])表示i结点放士兵的最优值累加上v结点放士兵的最优值和v结点不放士兵的最优值.

2.dp[i][1]+=dp[v][0] 很自然的就是i结点不放士兵的最优值累加上v结点放士兵的最优值,因为要覆盖每一条边,所以必须一条边必须有一点要有士兵.

v为i的儿子节点.

#include <iostream>#include <cstdio>#include <memory.h>#include <vector>using namespace std;const int maxn=1510;vector<int>g[maxn];int fa[maxn],dp[maxn][2],n;char buf[100];void dfs(int u){if(dp[u][1]!=-1){return;}dp[u][0]=1;dp[u][1]=0;for (int i=0;i<g[u].size();++i){dfs(g[u][i]);dp[u][0]+=min(dp[g[u][i]][1],dp[g[u][i]][0]);dp[u][1]+=dp[g[u][i]][0];}}int main(){while (scanf("%d",&n)==1){memset(fa,-1,sizeof(fa));memset(dp,-1,sizeof(dp));for (int i=0;i<n;++i){g[i].clear();}for (int i=0;i<n;++i){int u,m,v;scanf("%d:(%d)",&u,&m);while (m--){scanf("%d",&v);g[u].push_back(v);fa[v]=u;}}int r=0;while (fa[r]!=-1){r=fa[r];}dfs(r);printf("%d\n",min(dp[r][0],dp[r][1]));}return 0;}