[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<<"\n"; 44 } 45 return 0; 46 }