Classic tree DP problem: we know that the father and son nodes of a tree cannot appear at the same time, then we can get two states, select the parent node and not select the parent node
f[u][0]: select from all subtrees rooted at u, and not select the plan of u point f[u][1]: select from all subtrees rooted at u, and select u Point plan
For f[u][0] if this node is not selected, then we have two choices, all of its child nodes can be selected or not, then choose the largest one from these two cases to f[u][ 0]=∑max(f[si,0],f[si,1])
For f[u][1] to select this node, then we cannot select all its child nodes, then there is only one case f[u][1]=∑(f[si,0])
Code
#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<algorithm>usingnamespace std;constint N =6010;int n;int happy[N];int h[N], e[N], ne[N], idx;//邻接表存图int f[N][2];bool is[N];//这个点是否父节点//添加一条a-->b的边voidadd(int a,int b){
e[idx]= b;
ne[idx]= h[a];
h[a]= idx++;}voiddfs(int u){
f[u][1]+= happy[u];for(int i = h[u]; i !=-1; i = ne[i]){
int j = e[i];dfs(j);
f[u][0]+=max(f[j][0], f[j][1]);
f[u][1]+= f[j][0];}}intmain(){
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);memset(h,-1,sizeof h);
cin >> n;for(int i =1; i <= n; i++) cin >> happy[i];for(int i =1; i < n; i++){
int a, b;
cin >> a >> b;
is[a]=true;//标记此节点不是父节点add(b, a);}int root =1;while(is[root]) root++;dfs(root);
cout <<max(f[root][0], f[root][1])<< endl;return0;}