题目链接:这里 题意 给你一棵树,让你找到其中的两个子树,使得子树和最大。 要求子树不相交。 题解 树形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); }