题中的“序列”:

联通块,也就是树上的一棵小树;

 

与其说是dp,思想更像贪心:

强制dp[i]为必选i时的最优解

若子树的贡献>0则加入

在过程中比较答案即可;

 

喜闻乐见不开longlong见祖宗;

--

#include<bits/stdc++.h>
using namespace std;
int n,t=0,head[1000000],book[1000000];
long long ans=0,dp[1000000],a[1000000];
struct lys{
    int next,to;
}edge[1000000];
void add(int from,int to)
{   
    edge[++t].next=head[from];
    edge[t].to=to;
    head[from]=t;
}
void dfs(int x,int fa)
{  book[x]=1;
    for(int i=head[x];i;i=edge[i].next)
    {
        int to=edge[i].to;
        if(to==fa) continue;
        //cout<<x<<" "<<to<<endl;
        dfs(to,x);
    }
    dp[x]=a[x];
    for(int i=head[x];i;i=edge[i].next)
    {
        int to=edge[i].to;
        if(to==fa) continue;
        if(dp[to]>0)
        {
            dp[x]+=dp[to];
        }
    } 
    //cout<<x<<" "<<dp[x]<<endl;
    ans=max(ans,dp[x]);
}
int main( )
{
    //freopen("lys.in","r",stdin);
    
    memset(head,0,sizeof(head));
    
   cin>>n;
   
   for(int i=1;i<=n;i++)
   {
       cin>>a[i];
   } 
     
    for(int i=1;i<=n-1;i++)
    {
        int a,b;
        cin>>a>>b;
        add(a,b);
        add(b,a);
     } 
     dfs(1,0); 
     cout<<ans;
}