[poj2342]Anniversary party树形dp入门

题意:选出不含直接上下司关系的最大价值。

解题关键:树形dp入门题,注意怎么找出根节点,运用了并查集的思想。

转移方程:dp[i][1]+=dp[j][0];/i是j的子树

     dp[i][0]+=max(dp[j][0],dp[j][1]);

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cstdlib>
 5 #include<iostream>
 6 #include<cmath>
 7 #include<vector>
 8 using namespace std;
 9 typedef long long ll;
10 const int maxn=7000;
11 vector<int>G[maxn];
12 int father[maxn];
13 int dp[6005][2];
14 void dfs(int u,int fa){
15     int s=(int)G[u].size();
16     for(int i=0;i<s;i++){
17         int v=G[u][i];
18         if(v==fa) continue;
19         dfs(v,u);
20         dp[u][1]+=dp[v][0];
21         dp[u][0]+=max(dp[v][0],dp[v][1]);
22     }
23 }
24 int main(){
25     int n;
26     while(cin>>n){
27         memset(father, -1, sizeof father);
28         int a,b;
29         for(int i=1;i<=n;i++){
30             cin>>dp[i][1];
31         }
32         int root=1;
33         for(int i=0;i<n-1;i++){
34             cin>>a>>b;
35             G[b].push_back(a);
36             father[a]=b;
37             root=b;
38         }
39         cin>>a>>b;
40         while(father[root]!=-1) root=father[root];
41         dfs(root,0);
42         int ans=max(dp[root][0],dp[root][1]);
43         cout<<ans<<"
";
44     }
45     return 0;
46 }
原文地址:https://www.cnblogs.com/elpsycongroo/p/7413644.html