您的位置:首页 > 其它

ZOJ 1134 Strategic Game(树形DP)

2013-04-28 21:54 295 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: