zoukankan      html  css  js  c++  java
  • F:Maximum White Subtree(dp)

    Maximum White Subtree

    思路

    如果考虑其覆盖范围只会到其子树上,不会到其父节点上的话(假设的情况),这道题就非常好写了,就是一个简单的自底向上传递的树形(dp)。所以我们还要考虑的就是连接其父节点,因此我们只需要再进行一个自顶下向传递的树形(dp)即可。

    第一遍的(dfs)比较简单,但是第二遍的(dfs)有一些细节需要考虑,我在下面的代码中给出了注释。

    写完后找了题解,好像这是换根(dp?),蒟蒻我没有学过啥换根(dp)

    代码

    #include <bits/stdc++.h>
    #define mp make_pair
    #define pb push_back
    
    using namespace std;
    
    typedef pair<int, int> pii;
    typedef long long ll;
    typedef unsigned long long ull;
    
    const double eps = 1e-7;
    const double pi = acos(-1.0);
    const int inf = 0x3f3f3f3f;
    
    inline ll read() {
        ll f = 1, x = 0;
        char c = getchar();
        while(c < '0' || c > '9') {
            if(c == '-') f = -1;
            c = getchar();
        } 
        while(c >= '0' && c <= '9') {
            x = (x << 1) + (x << 3) + (c ^ 48);
            c = getchar();
        }
        return f * x;
    }
    
    const int N = 2e5 + 10;
    
    int head[N], nex[N << 1], to[N << 1], cnt = 1;
    int dp[N], a[N], n;
    
    void add(int x, int y) {
        to[cnt] = y;
        nex[cnt] = head[x];
        head[x] = cnt++;
    }
    
    void dfs1(int rt, int fa) {
        if(a[rt] == 0)  dp[rt] = -1;//设置dp数组的初值,这个应该比较简单理解。
        else dp[rt] = 1;
        for(int i = head[rt]; i; i = nex[i]) {
            if(to[i] == fa) continue;
            dfs1(to[i], rt);
            dp[rt] = max(dp[rt], dp[rt] + dp[to[i]]);//两种选择,与其子树连接或者不连接。
        }
    }
    
    void dfs2(int rt, int fa) {
        for(int i = head[rt]; i; i = nex[i]) {
            if(to[i] == fa) continue;
            dp[to[i]] = max(dp[to[i]], dp[to[i]] + dp[rt] - max(dp[to[i]], 0));
            //这个的de[rt] - max(dp[to[i]], 0),表示的意思是:如果这个节点在上一躺的dfs中选择了这个儿子节点那么这个点一定是正数,如果这个点是负数,那么他在上一躺就没有被选择到,所以我们不需要减去这个点的值。
            dfs2(to[i], rt);
        }
    }
    
    int main() {
        // freopen("in.txt", "r", stdin);
        // freopen("out.txt", "w", stdout);
        // ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
        n = read();
        for(int i = 1; i <= n; i++) a[i] = read();
        for(int i = 1; i < n; i++) {
            int x = read(), y = read();
            add(x, y);
            add(y, x);
        }
        dfs1(1, -1);
        dfs2(1, -1);
        for(int i = 1; i <= n; i++)
            printf("%d%c", dp[i], i == n ? '
    ' : ' ');
        return 0;
    }
    
  • 相关阅读:
    RocketMQ源码分析:(二)消息发送的三种方式
    LTS本地搭建详述
    Mac端解决(含修改8.0.13版的密码):Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
    flink入门:01 构建简单运行程序
    rocketmq控制台搭建(rocketmq-console)
    在consul上注册web服务
    将filenames里的每个字符串输出到out文件对象中注意行首的缩进
    spidermark sensepostdata ntp_monlist.py
    HTTP Error 403没有了,但是中文全都是乱码。又是怎么回事?
    original.txt和提交的页面输出的文字的混合文件
  • 原文地址:https://www.cnblogs.com/lifehappy/p/13169124.html
Copyright © 2011-2022 走看看