CF1324F Maximum White Subtree(树形dp)

Maximum White Subtree

思路:我们假设节点1为root,如果我们知道了root所有子树的最优情况,那么我们可以把1节点的最优情况传递给它的所有子树(当然如果传递给如图2的子树,那么需要把以2为root的最优贡献给减去,再传递root[1]的最优价值)。那我们这么维护子树的最优情况?很显然,如果子树的价值是负数,那么子树给父结点的价值应该是0,如果是正数,则可以把这个价值传递给父结点。

 1 #include <iostream>
 2 #include <deque>
 3 #include <algorithm>
 4 #include <stack>
 5 #include <vector>
 6 #include <cstring>
 7  
 8 using namespace std;
 9  
10 const int N = 2e5 + 10;
11  
12 struct Tree{
13     int cnt;
14     bool white;
15 }tree[N];
16 struct Edge{
17     int to, nxt;
18 }e[N << 1];
19 int head[N];
20 int n, tot;
21  
22 inline void add(int u, int v){
23     e[tot].to = v; e[tot].nxt = head[u]; head[u] = tot++;
24     e[tot].to = u; e[tot].nxt = head[v]; head[v] = tot++;
25 }
26  
27 int process(int now, int pre){
28     int cnt = 0;
29     for(int o = head[now]; ~o; o = e[o].nxt){
30         if(e[o].to != pre){
31             cnt += process(e[o].to, now);
32         }
33     }
34     tree[now].cnt = tree[now].white ? 1 : -1; //自身是否是白色
35     tree[now].cnt += cnt > 0 ? cnt : 0; //子树给的价值
36     return max(tree[now].cnt, 0); //返回最优价值
37 }
38  
39 void push_down(int now, int pre){
40     for(int o = head[now]; ~o; o = e[o].nxt){
41         if(e[o].to != pre){
42             if(tree[now].cnt > 0){ //如果父结点价值为正,则传递价值
43                 //如果该子树价值为正,则父结点传递的价值减去该子树传递的价值
44                 //否则直接传递父结点的价值
45                 if(tree[e[o].to].cnt > 0) tree[e[o].to].cnt += max(tree[now].cnt - tree[e[o].to].cnt, 0);
46                 else tree[e[o].to].cnt += tree[now].cnt;
47             }
48             push_down(e[o].to, now);
49         }
50     }
51 }
52  
53 void solve(){
54  
55     cin >> n;
56     for(int i = 1; i <= n; ++i) head[i] = -1; tot = 0;
57     for(int i = 1; i <= n; ++i){
58         cin >> tree[i].white;
59     }
60     int u, v;
61     for(int i = 1; i < n; ++i){
62         cin >> u >> v;
63         add(u, v);
64     }
65     process(1, 0);
66     push_down(1, 0);
67     for(int i = 1;i <= n; ++i) cout << tree[i].cnt << " ";
68     cout << endl;
69 }
70  
71 int main(){
72     
73     ios::sync_with_stdio(false);
74     cin.tie(0);
75     cout.tie(0);
76     solve();
77     
78     return 0;
79 }
原文地址:https://www.cnblogs.com/SSummerZzz/p/12707022.html