zoukankan      html  css  js  c++  java
  • CodeForces 1324F Maximum White Subtree

    题意

    给定一棵(n)个节点的无根树,每个节点为黑色或者白色,每个点的答案为包含该点的子树(指无根子树)的白色节点数减黑色节点数的最大值

    分析

    对于无根树的题一般指定某一个点为根,不妨设为(1)

    我们发现对于(1)号节点,他的某棵子树(将(1)视为根)如果白色节点数大于黑色节点数,则他的答案加上该差值

    我们先采用树形(DP)将所有节点都这样统计一遍,这样就获得了来自子树的贡献

    (a[i])为以(i)为根,所有白色节点数大于黑色节点数的子树的贡献

    然后对于除(1)节点以外所有节点,还需要统计与父亲这一棵无向子树的关系

    设遍历到(now)节点,子树节点为(to)节点

    • (a[to]>0),则(now)的答案子树包括(to)节点,(to)节点选择(now)的答案子树和(to)的答案子树中的最大值(因为已经包括,所以不是加和)

      [a[to] = max(a[to], a[now]) ]

    • (a[to]leq0),则(now)的答案子树不包括(to)节点,(to)节点选择与(now)的答案子树进行拼接或不拼接的最大值(因为不包括,所以是加和)

      [a[to] = max(a[to], a[now] + a[to]) ]

    #pragma GCC optimize(3, "Ofast", "inline")
    
    #include <bits/stdc++.h>
    
    #define start ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    #define ll long long
    #define int ll
    #define ls st<<1
    #define rs st<<1|1
    #define pii pair<int,int>
    using namespace std;
    const int maxn = (ll) 3e5 + 5;
    const int mod = 1000000007;
    const int inf = 0x3f3f3f3f;
    vector<int> v[maxn];
    int a[maxn];
    
    void dfs(int now, int pre) {
        for (auto &to:v[now]) {
            if (to == pre)
                continue;
            dfs(to, now);
            if (a[to] > 0)
                a[now] += a[to];
        }
    }
    
    void dfs2(int now, int pre) {
        for (auto &to:v[now]) {
            if (to == pre)
                continue;
            if (a[to] > 0)
                a[to] = max(a[to], a[now]);
            else
                a[to] = max(a[to], a[now] + a[to]);
            dfs2(to, now);
        }
    }
    
    signed main() {
        start;
        int n;
        cin >> n;
        for (int i = 1; i <= n; ++i) {
            cin >> a[i];
            if (a[i] == 0)
                a[i] = -1;
        }
        for (int i = 1; i < n; ++i) {
            int x, y;
            cin >> x >> y;
            v[x].push_back(y);
            v[y].push_back(x);
        }
        dfs(1, 0);
        dfs2(1, 0);
        for (int i = 1; i <= n; ++i)
            cout << a[i] << ' ';
        return 0;
    }
    
  • 相关阅读:
    深入理解Java内存模型(JMM)
    Java基础知识①
    Java自旋锁的几种实现
    ConcurrentHashMap的CAS操作
    Java集合对比总结
    python模块--os模块
    python模块--random
    Datafactory 学习笔记
    Datafactory 实际使用案例
    Oracle三种排名函数使用
  • 原文地址:https://www.cnblogs.com/F-Mu/p/12485577.html
Copyright © 2011-2022 走看看