题目链接:这里
题意
给你一棵树,让你找到其中的两个子树,使得子树和最大。
要求子树不相交。
题解
树形dp,dp[i]表示以i为根的子树里面存在的子树最大值是多少
记录最大值和次大值,俩加起来就是最大的。
//743 D
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5+7;
const long long inf = 1e12;
long long a[maxn], dp[maxn], flag, ans = -inf;
int n;
vector <int> E[maxn];
void dfs1(int x, int fa){
dp[x] = a[x];
for(int i = 0; i < E[x].size(); i++){
int v = E[x][i];
if(v == fa) continue;
dfs1(v, x);
dp[x] += dp[v];
}
}
void dfs2(int x, int fa){
long long mx1 = -inf, mx2 = -inf;
for(int i = 0; i < E[x].size(); i++){
int v = E[x][i];
if(v == fa) continue;
dfs2(v, x);
if(dp[v] >= mx1){
mx2 = mx1;
mx1 = dp[v];
}
else if(dp[v] > mx2){
mx2 = dp[v];
}
dp[x] = max(dp[x], dp[v]);
}
if(mx1 != -inf && mx2 != -inf){
ans = max(ans, mx1 + mx2);
flag = 1;
}
}
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%lld", &a[i]);
for(int i = 1; i < n; i++){
int u, v;
scanf("%d%d", &u, &v);
E[u].push_back(v);
E[v].push_back(u);
}
dfs1(1, -1);
dfs2(1, -1);
if(!flag) puts("Impossible");
else printf("%lld\n", ans);
}