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即可。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<vector>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn = 6666;
 7 int dp[maxn][2];//dp[i][0]表示第i个人不去,dp[i][1]表示第i个人去 
 8 struct node{
 9     int f;//父节点 
10     vector<int>s;//子节点 
11 };
12 node tree[maxn];
13 int dfs(int cur){
14     for(int i = 0;i<tree[cur].s.size();i++){
15         dfs(tree[cur].s[i]);
16         dp[cur][1] += dp[tree[cur].s[i]][0];
17         dp[cur][0] += max(dp[tree[cur].s[i]][1],dp[tree[cur].s[i]][0]);
18     }
19 }
20 int main(){
21     int n;
22     while(scanf("%d",&n)!=EOF){
23         memset(dp,0,sizeof(dp));
24         for(int i = 1;i<=n;i++)
25             scanf("%d",&dp[i][1]);
26         int l,k;
27         while(scanf("%d%d",&l,&k)&&(l||k)){
28             tree[l].f = k;
29             tree[k].s.push_back(l);
30         }
31         //寻找根节点 
32         int root = 1;
33         while(tree[root].f)
34             root = tree[root].f;
35         dfs(root);
36         printf("%d\n",max(dp[root][0],dp[root][1]));
37     }
38     return 0;
39 }

 

posted @ 2016-07-22 10:34  Esieve  阅读(205)  评论(0编辑  收藏  举报