1. 程式人生 > >[poj2342]Anniversary party樹形dp入門

[poj2342]Anniversary party樹形dp入門

roo poj2342 ++ def poj ive tin names const

題意:選出不含直接上下司關系的最大價值。

解題關鍵:樹形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<<"\n"; 44 } 45 return 0; 46 }

[poj2342]Anniversary party樹形dp入門