一个简单的树形dp
dp[i][0]表示不选i结点
dp[i][0] = sum(max(dp[son[i]][1],dp[son[i]][0]))
dp[i][1]表示选i结点
dp[i][1] = sum(dp[son[i]][0])
#include <iostream> #include <cstdio> #include <algorithm> #define INF -150*6010 using namespace std; int n, convi[6010], num_son[6010]; short son[6010][1000]; int dp[6010][2]; int dynamic_0(int fat); int dynamic_1(int fat); int dynamic_0(int fat) { if(dp[fat][0] > INF) return dp[fat][0]; int sum = 0; for(int i = 0 ; i < num_son[fat] ; i++) { sum += max(dynamic_1(son[fat][i]),dynamic_0(son[fat][i])); } dp[fat][0] = sum; return sum; } int dynamic_1(int fat) { if(dp[fat][1] > INF) return dp[fat][1]; int sum = convi[fat]; for(int i = 0 ; i < num_son[fat] ; i++) { sum += dynamic_0(son[fat][i]); } dp[fat][1] = sum; return sum; } int main() { scanf("%d",&n); for(int i = 1 ; i <= n ; i++) { scanf("%d",&convi[i]); num_son[i] = 0; } int l,k; while(scanf("%d%d",&l,&k) && l && k) { son[k][num_son[k]] = l; num_son[k]++; } for(int i = 1 ; i <= n ; i++) { if(num_son[i] == 0) { dp[i][0] = 0; dp[i][1] = convi[i]; } else { dp[i][0] = dp[i][1] = INF; } } for(int i = 1 ; i <= n ; i++) { dynamic_0(i); dynamic_1(i); } int ans = INF; for(int i = 1 ; i <= n ; i++) { if(ans < dp[i][0]) ans = dp[i][0]; if(ans < dp[i][1]) ans = dp[i][1]; } printf("%d\n",ans); return 0; }