#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef long long LL;
LL f[N];
int h[N],w[N],e[N*2],ne[N*2],idx;
int n;
void add(int a,int b) // 数组模拟邻接表
{
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int u,int father) // 树的递归
{
f[u]=w[u];
for(int i=h[u];i!=-1;i=ne[i])
{
int j=e[i];
if(j!=father)
{
dfs(j,u);
f[u]+=max(0LL,f[j]); // 求权值最大的连通块,如果为负数就取零 且max函数中两个参数类型要一致,故0要变成0LL
}
}
}
int main()
{
cin>>n;
memset(h,-1,sizeof h) ; // 邻接表一定要记得初始化h数组
for(int i=1;i<=n;i++) cin>>w[i];
for(int i=0;i<n-1;i++) // n-1条边
{
int a,b;
cin>>a>>b;
add(a,b),add(b,a); // 无向边
}
dfs(1,-1); // 树形dp多用递归,可暴搜,因为是无向边,防止循环,所以加上第二参数父节点
LL res=f[1];
for(int i=2;i<=n;i++) res=max(res,f[i]); // 递归出来求最大的一个连通块即可
cout<<res<<endl;
return 0;
}
12-24
538
10-02
1120
09-28
1242