• 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 }
  • 相关阅读:
    JavaScript坑
    maven学习
    JAVA多线程和并发基础面试问答(转)
    Redis与Memcached的区别(一)
    poi生成execl综合
    POI操作Excel常用方法总结(转)
    java中在创建对象时候的初始化顺序
    [Java Web]敏感词过滤算法
    orcle导入导出
    js动态时间
  • 原文地址:https://www.cnblogs.com/SSummerZzz/p/12707022.html
Copyright © 2020-2023  润新知