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 << "\n";
    }
    
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/shandongs1/p/9849813.html
83
今日推荐