都是基础啊,因为我也才刚学.
凡是涉及树形dp,你就得先知道怎么转移.
一般dp问题是解决max/min.那么这个dp问题也是解决max和min,但是怎么解决呢?
很容易想到这个dp的表示方式.
开两维:dp[u][0/1]表示以u为根节点的子树,选不选u节点所获得的最大权值,然后配合dfs更新子树信息转移即可.转移方程大概是:

假设u节点的子节点为x.
dp[u][1]=max(dp[u][1],w[u]+dp[x][0]);
dp[u][0]=max(dp[u][0],dp[x][1]);

然后就是写代码了..
代码如下:

#include <bits/stdc++.h>
using namespace std;
const int N=6e3+5;
vector<int>v[N];
int w[N];
int dp[N][2];
inline void dfs(int u,int s)//儿子 父亲
{
    for(int i=0;i<v[u].size();i++)
    {
        int x=v[u][i];
        if(s==x) continue;
        dfs(x,u);
        dp[u][1]+=dp[x][0];
        dp[u][0]+=max(dp[x][1],dp[x][0]);
    }
    dp[u][1]+=w[u];
}

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&w[i]);
    }
    for(int i=1;i<n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        v[x].push_back(y);
        v[y].push_back(x);
    }
    dfs(1,0);
    /*
    for(int i=0;i<v[4].size();i++)
    {
        cout<<v[4][i]<<' ';
    }cout<<endl;*/
    //cout<<dp[4][0]<<endl;
    cout<<max(dp[1][0],dp[1][1])<<endl;
    return 0;
}
/*
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
*/