标签:
本题可用树形DP求解(即在树上DP).
father数组记录节点父亲,ch容器记录儿子。
dp[i][0]表示以节点i为跟的子树的最大总权值(不选点i),dp[i][1]表示选点i。
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<queue> #include<set> #include<map> #include<vector> #include<cmath> #define ll __int64 #define INF 0x3fffffff #define MAXN 6005 using namespace std; int n; int dp[MAXN][2]; int a[MAXN],father[MAXN],vis[MAXN]; vector<vector<int> >ch(6005); void tree_dp(int root) { vis[root]=1; for(int i=0;i<ch[root].size();i++) { int j=ch[root][i]; if(!vis[j]) { tree_dp(j); dp[root][0]+=max(dp[j][1],dp[j][0]); dp[root][1]+=dp[j][0]; } } } int main() { //freopen("d:\\Test.txt","r",stdin); while(~scanf("%d",&n)) { for(int i=1; i<=n; i++) scanf("%d",&a[i]); memset(vis,0,sizeof(vis)); memset(dp,0,sizeof(dp)); memset(father,0,sizeof(father)); for(int i=0;i<=n;i++) ch[i].clear(); for(int i=1; i<=n; i++) dp[i][1]=a[i]; int c,f; while(scanf("%d%d",&c,&f),c||f) { father[c]=f; ch[f].push_back(c); } int root=1; while(father[root]) root=father[root]; tree_dp(root); cout<<max(dp[root][0],dp[root][1])<<endl; } return 0; }
hdu 1520 Anniversary party(树形DP)
标签:
原文地址:http://blog.csdn.net/u012198382/article/details/45153791