POJ2342 树形dp

时间:2023-03-09 00:55:50
POJ2342 树形dp

原题:http://poj.org/problem?id=2342

树形dp入门题。

我们让dp[i][0]表示第i个人不去,dp[i][1]表示第i个人去 ,根据题意我们可以很容易的得到如下递推公式:

dp[father][1] += dp[son][0]

dp[father][0] += max(dp[son][0],dp[son][1]);

找到这棵树的根节点,对树向下深搜的过程中进行dp即可。

 #include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = ;
int dp[maxn][];//dp[i][0]表示第i个人不去,dp[i][1]表示第i个人去
struct node{
int f;//父节点
vector<int>s;//子节点
};
node tree[maxn];
int dfs(int cur){
for(int i = ;i<tree[cur].s.size();i++){
dfs(tree[cur].s[i]);
dp[cur][] += dp[tree[cur].s[i]][];
dp[cur][] += max(dp[tree[cur].s[i]][],dp[tree[cur].s[i]][]);
}
}
int main(){
int n;
while(scanf("%d",&n)!=EOF){
memset(dp,,sizeof(dp));
for(int i = ;i<=n;i++)
scanf("%d",&dp[i][]);
int l,k;
while(scanf("%d%d",&l,&k)&&(l||k)){
tree[l].f = k;
tree[k].s.push_back(l);
}
//寻找根节点
int root = ;
while(tree[root].f)
root = tree[root].f;
dfs(root);
printf("%d\n",max(dp[root][],dp[root][]));
}
return ;
}