Codeforces Round #384 (Div. 2) D. Chloe and pleasant prizes 树形DP

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 }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值