• Codeforces 1324F Maximum White Subtree


    题目链接

    题解:经典的树形DP,跑两遍即可,第一遍记录出每个点为根时向下所能构成的最大的值(cnt_{w}-cnt_{b}),第二遍统计出每个点为根时的答案,此时的根包括其父,所以在第二次dfs时要减去再回溯

    #include<bits/stdc++.h>
    using namespace std;
    #define ms(x,y) memset(x, y, sizeof(x))
    #define lowbit(x) ((x)&(-x))
    typedef long long LL;
    typedef pair<int,int> pii;
    
    
    void run_case() {
        int n; cin >> n;
        vector<int> a(n), dp(n), ans(n);
        for(int i = 0; i < n; ++i) {
            cin >> a[i];
            if(a[i] == 0) a[i] = -1;
        }
        vector<vector<int>> G(n+1);
        for(int i = 1; i < n; ++i) {
            int u, v;
            cin >> u >> v;
            u--, v--;
            G[u].push_back(v);
            G[v].push_back(u);
        }
        function<void(int, int)> dfs1 = [&](int u, int fa) {
            dp[u] = a[u];
            for(auto v: G[u]) {
                if(v == fa) continue;
                dfs1(v, u);
                dp[u] += max(0, dp[v]);
            }
        };
        function<void(int, int)> dfs2 = [&](int u, int fa) {
            ans[u] = dp[u];
            for(auto v: G[u]) {
                if(v == fa) continue;
                dp[u] -= max(0, dp[v]);
                dp[v] += max(0, dp[u]);
                dfs2(v, u);
                dp[v] -= max(0, dp[u]);
                dp[u] += max(0, dp[v]);
            }
        };
        dfs1(1, -1);
        dfs2(1, -1);
        for(auto i : ans) cout << i << " ";
    }
    
    int main() {
        ios::sync_with_stdio(false), cin.tie(0);
        cout.flags(ios::fixed);cout.precision(2);
        //int t; cin >> t;
        //while(t--)
        run_case();
        cout.flush();
        return 0;
    }
    
  • 相关阅读:
    重塑矩阵
    数组拆分
    最大连续1的个数
    石子游戏
    概率与期望知识总结
    洛谷 P3951 NOIP 2017 小凯的疑惑
    关于结构体的初始化
    山海经:线段树维护最大子段和
    偏序 分块+bitset
    分块练习C. interval
  • 原文地址:https://www.cnblogs.com/GRedComeT/p/12494971.html
Copyright © 2020-2023  润新知