这是一道经典的树形dp的题,转移状态实际上就两个
1.图片说明
2.图片说明
其中v为x的儿子,然后就可以如下写代码了

#include <iostream>
#include<stdio.h>
#include<string>
#include<string.h>
#include<map>
#include<queue>
#include<deque>
#include<vector>
#include<algorithm>
#include<set>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn=6e3+100;
const int maxe=4e4+100;
const ll inf=1e18;
const ll _inf=-1e17;
const double pi=acos(-1);
const int mod=1e9+7;

inline int readii(){
    int sgn = 1; int cnt = 0;char ch = getchar();
    while (ch < '0' || ch > '9') {if(ch == '-')sgn = -sgn;ch = getchar();}
    while ('0' <= ch && ch <= '9') {cnt = cnt*10 + (ch-'0');ch = getchar();}
    return  sgn*cnt;
}
inline int readll(){
    int sgn = 1; int cnt = 0;char ch = getchar();
    while (ch < '0' || ch > '9') {if(ch == '-')sgn = -sgn;ch = getchar();}
    while ('0' <= ch && ch <= '9') {cnt = cnt*10 + (ch-'0');ch = getchar();}
    return  sgn*cnt;
}
int n;
int happy[maxn];
ll dp[maxn][2];
vector<int> G[maxn];
ll ans=_inf;
void dfs(int x,int fa)
{
    for(int i=0;i<G[x].size();i++)
    {
        int v=G[x][i];
        if(v==fa) continue;
        dfs(v,x);
        dp[x][1]=max(dp[x][1],dp[x][1]+dp[v][0]);
        dp[x][0]=max({dp[x][0],dp[x][0]+dp[v][1],dp[x][0]+dp[v][0]});
        /*注意这个地方,一定要放一起写,不能分开,因为只能在两种中挑一个,分开则变成了可以挑和不挑同时都可以选*/
    }
   // printf("dp[%d][0] = %lld, dp[%d][1] = %lld\n",x,dp[x][0],x,dp[x][1]);
    ans=max(ans,dp[x][0]);
    ans=max(ans,dp[x][1]);
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) {scanf("%d",&happy[i]);dp[i][0]=0;dp[i][1]=happy[i];}
    int L,k;
    for(int i=1;i<=n-1;i++)
    {
        scanf("%d%d",&L,&k);
        G[L].push_back(k);
        G[k].push_back(L);
    }
    scanf("%d%d",&L,&k);
    dfs(1,-1);
    printf("%lld\n",ans);
    return 0;
}