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; }