D. Chloe and pleasant prizes
链接:
http://codeforces.com/contest/743/problem/D
题解:
对于每个以该点为子树的节点 他都有两种可能的取值 一个是dp[i],一个为 num[i] 。dp[i] 表示以该点为根的子树当中权值
最大的, num[i]表示以 该点为根的子树 的所有权值(包括自己);
我们要想使两个子树的和最大,那么就是在以该点为根的子树当中找到两个 和最大的即可。
代码:
1 #include <map> 2 #include <set> 3 #include <cmath> 4 #include <queue> 5 #include <stack> 6 #include <cstdio> 7 #include <string> 8 #include <vector> 9 #include <cstring> 10 #include <sstream> 11 #include <iostream> 12 #include <algorithm> 13 #include <functional> 14 using namespace std; 15 #define rep(i,a,n) for (int i=a;i<=n;i++) 16 #define per(i,a,n) for (int i=n;i>=a;i--) 17 #define pb push_back 18 #define mp make_pair 19 #define all(x) (x).begin(),(x).end() 20 #define SZ(x) ((int)(x).size()) 21 typedef vector<int> VI; 22 typedef long long ll; 23 typedef pair<int, int> PII; 24 const ll mod = 1e9 + 7; 25 //const int inf = 0x3f3f3f3f; 26 const double eps = 1e-7; 27 // head 28 29 const int maxn = 2e5 + 100; 30 vector<int>e[maxn]; 31 ll a[maxn], sum[maxn], dp[maxn], ans; 32 int vis[maxn]; 33 const ll inf = (ll)1e18 + 7; 34 35 void dfs(int rt) { 36 vis[rt] = 1; 37 ll Max = -inf, Min = -inf; 38 sum[rt] = a[rt]; 39 rep(i, 0, int(e[rt].size() - 1)) { 40 int son = e[rt][i]; 41 if (vis[son]) continue; 42 dfs(son); 43 sum[rt] += sum[son]; 44 if (sum[son] > dp[son]) dp[son] = sum[son]; 45 if (dp[son] > dp[rt]) Min = Max, Max = dp[son], dp[rt] = Max; 46 else Min = max(Min, dp[son]); 47 if (Min != -inf) ans = max(ans, Max + Min); 48 } 49 } 50 51 int main() { 52 ios::sync_with_stdio(false); 53 int n, u, v; 54 cin >> n; 55 rep(i, 1, n) cin >> a[i]; 56 rep(i, 1, n) dp[i] = -inf; 57 rep(i, 2, n) { 58 cin >> u >> v; 59 e[u].pb(v); 60 e[v].pb(u); 61 } 62 ans = -inf; 63 dfs(1); 64 if (ans == -inf) cout << "Impossible" << endl; 65 else cout << ans << endl; 66 return 0; 67 }