再次对树进行深搜对于每个节点,把他的所有祖先节点的值和子孙节点的值在线段树上减去INF,此时求出最大值p,再加上该节点的值更新ans
#include <bits/stdc++.h>
#define maxn 200005
#define INF 2e15
typedef long long ll;
using namespace std;
struct Node{
int l, r;
}node[maxn];
int p[maxn], cnt, sum[maxn], n, e;
ll d[maxn], num[maxn], T[maxn<<2], ans = -INF;
vector<int> v[maxn];
void dfs1(int j, int f){
p[++cnt] = j;
node[j].l = cnt;
sum[j] = 1;
for(int i = 0; i < v[j].size(); i++){
int h = v[j][i];
if(h != f){
dfs1(h, j);
d[j] += d[h];
sum[j] += sum[h];
}
}
d[j] += num[j];
node[j].r = cnt;
}
void Build(int s, int l, int r){
if(l == r){
T[s] = d[p[l]];
return ;
}
int mid = (l + r) >> 1;
Build(s<<1, l, mid);
Build(s<<1|1, mid+1, r);
T[s] = max(T[s<<1], T[s<<1|1]);
}
void Update(int s, int l, int r, int L, int R, ll c){
if(l == L && R == r){
T[s] += c;
return ;
}
int mid = (L + R) >> 1;
if(r <= mid)
Update(s<<1, l, r, L, mid, c);
else if(l > mid)
Update(s<<1|1, l, r, mid+1, R, c);
else{
Update(s<<1, l, mid, L, mid, c);
Update(s<<1|1, mid+1, r, mid+1, R, c);
}
T[s] = max(T[s<<1], T[s<<1|1]);
}
void dfs2(int j, int f, int h){
++e;
int kk = e;
Update(1, kk, kk, 1, n, (ll)-INF);
for(int i = 0; i < v[j].size(); i++){
int s = v[j][i];
if(s != f){
if(h + sum[s] != n){
Update(1, node[s].l, node[s].r, 1, n, (ll)-INF);
ans = max(ans, d[s] + T[1]);
Update(1, node[s].l, node[s].r, 1, n, (ll)INF);
}
dfs2(s, j, h+1);
}
}
Update(1, kk, kk, 1, n, (ll)INF);
}
int main(){
// freopen("in.txt", "r", stdin);
int a, b;
scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%I64d", num+i);
for(int i = 1; i < n; i++){
scanf("%d%d", &a, &b);
v[a].push_back(b);
v[b].push_back(a);
}
dfs1(1, -1);
Build(1, 1, n);
dfs2(1, -1, 1);
if(ans == -INF)
puts("Impossible");
else
printf("%I64d\n", ans);
return 0;
}