zoukankan      html  css  js  c++  java
  • 83: 模拟赛 树形dp

    $des$

    $sol$

    维护每个点的子树中的信息以及非子树的信息

    $code$

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define gc getchar()
    inline int read() {
        int x = 0; char c = gc;
        while(c < '0' || c > '9') c = gc;
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc;
        return x;
    }
    
    #define Rep(i, a, b) for(int i = a; i <= b; i ++)
    
    const int N = 1e5 + 10;
    
    int f[N][3], g[N][3];
    int n, p;
    int deep[N], fa[N], size[N][2], sizeg[N][3];
    
    struct Node {
        int v, w, nxt;
    } G[N << 1];
    int cnt, head[N];
    
    void Link(int u, int v, int w) {
        G[++ cnt].v = v, G[cnt].w = w, G[cnt].nxt = head[u]; head[u] = cnt;
    }
    
    void Dfs1(int u, int f_, int dep) {
        deep[u] = dep, fa[u] = f_;
        for(int i = head[u]; ~ i; i = G[i].nxt) {
            int v = G[i].v;
            if(v == f_) continue;
            Dfs1(v, u, dep + 1);
        }
    }
    
    void Dfs2(int u) {
        for(int i = head[u]; ~ i; i = G[i].nxt) {
            int v = G[i].v, w = G[i].w;
            if(v == fa[u]) continue;
            Dfs2(v);
            if(w % 2) {
                size[u][0] += size[v][1];
                size[u][1] += size[v][0];
                size[u][1] ++;
                f[u][0] += f[v][1] + w * size[v][1];
                f[u][1] += f[v][0] + w * size[v][0] + w;
            } else {
                size[u][0] += size[v][0];
                size[u][1] += size[v][1];
                size[u][0] ++;
                f[u][0] += f[v][0] + w * size[v][0] + w;
                f[u][1] += f[v][1] + w * size[v][1];
            }
        }
    }
    
    void Dfs3(int u) {
        for(int i = head[u]; ~ i; i = G[i].nxt) {
            int v = G[i].v, w = G[i].w;
            if(v == fa[u]) continue;
            if(w % 2) {
                sizeg[v][1] ++;
                sizeg[v][1] += sizeg[u][0] + size[u][0] - size[v][1];
                sizeg[v][0] += sizeg[u][1] + size[u][1] - size[v][0] - 1;
                g[v][1] += g[u][0] + (f[u][0] - f[v][1]) - size[v][1] * w;
                g[v][1] += w * (sizeg[u][0] + size[u][0] - size[v][1] + 1);
                g[v][0] += g[u][1] + (f[u][1] - f[v][0]) - size[v][0] * w - w;
                g[v][0] += w * (sizeg[u][1] + size[u][1] - size[v][0] - 1);
            } else {
                sizeg[v][0] ++;
                sizeg[v][1] += sizeg[u][1] + size[u][1] - size[v][1];
                sizeg[v][0] += sizeg[u][0] + size[u][0] - size[v][0] - 1;
                g[v][1] += g[u][1] + (f[u][1] - f[v][1]) - size[v][1] * w;
                g[v][1] += w * (sizeg[u][1] + size[u][1] - size[v][1]);
                g[v][0] += g[u][0] + (f[u][0] - f[v][0]) - size[v][0] * w - w;
                g[v][0] += w * (sizeg[u][0] + size[u][0] - size[v][0] + 1 - 1);
            }
            Dfs3(v);
        }
    }
    
    int main() {
        n = read(), p = read();
        Rep(i, 1, n) head[i] = -1;
        Rep(i, 1, n - 1) {
            int u = read(), v = read(), w = read();
            Link(u, v, w), Link(v, u, w);
        }
        Dfs1(1, 0, 1);    
        Dfs2(1);
        Dfs3(1);
        Rep(pp, 1, p) {
            int x = read();
            int j = f[x][1] + g[x][1];
            int o = f[x][0] + g[x][0];
            cout << j << " " << o << "
    ";
        }
        
        return 0;
    }
  • 相关阅读:
    android 蓝牙串口通讯使用简介
    【C】C语言可变参va_start/va_arg/va_end使用说明
    【Codecs】CABAC深入分析与理解
    【Bugs】VS单步调试的无法进入断点、行号错乱等问题解决方法
    【SVAC1】NAL单元的封装
    【CV】傅里叶描绘子原理及应用简介
    【CV】骨架提取
    【SVAC】千目聚云:SVAC2.0已来 未来发展道路一片光明
    【Debug】当前不会命中断点,源代码与原始版本不同
    【Base】POE供电
  • 原文地址:https://www.cnblogs.com/shandongs1/p/9849813.html
Copyright © 2011-2022 走看看