题目链接:http://codeforces.com/contest/743/problem/D
大致思路挺简单的就是找到一个父节点然后再找到其两个字节点总值的最大值。
可以设一个dp[x]表示x节点及以下节点能得到的最大值,由于dfs的顺序我们
可以边dfs边求解ans=max(dp[x]+dp[v],ans)(由于dfs是先查询完dp[v]的
左边的树,所以得到的dp[x]是在v节点左边的最大值),顺便记录一下每个节
点的sum值因为一个节点要么整个子树包括自己都要算或者不算。
#include <iostream> #include <cstring> #include <vector> using namespace std; const int M = 2e5 + 10 , inf = 2e14; typedef long long ll; ll a[M] , dp[M] , sum[M] , ans; vector<int>vc[M]; void dfs(int pos , int pre) { int len = vc[pos].size(); ll temp = a[pos]; for(int i = 0 ; i < len ; i++) { int gg = vc[pos][i]; if(gg != pre) { dfs(gg , pos); temp += sum[gg]; if(dp[pos] != -inf) { ans = max(ans , dp[pos] + dp[gg]); } dp[pos] = max(dp[pos] , dp[gg]); } } sum[pos] = temp;; dp[pos] = max(dp[pos] , sum[pos]); } int main() { int n; cin >> n; for(int i = 1 ; i <= n ; i++) { cin >> a[i]; } for(int i = 1 ; i < n ; i++) { int x , y; cin >> x >> y; vc[x].push_back(y); vc[y].push_back(x); } ans = -inf; for(int i = 1 ; i <= n ; i++) { dp[i] = -inf; } dfs(1 , -1); if(ans == -inf) cout << "Impossible" << endl; else cout << ans << endl; return 0; }