From 6f7afdc56e9f82ea77724351b733e0e90d10c94d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B5=B7?= <10402852@qq.com> Date: Tue, 16 Jan 2024 15:04:57 +0800 Subject: [PATCH] 'commit' --- TangDou/Topic/HuanGenDp/P6419.cpp | 34 ++++++++++++++++----------- TangDou/Topic/【换根DP】专题.md | 20 +++++++++++++++- 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/TangDou/Topic/HuanGenDp/P6419.cpp b/TangDou/Topic/HuanGenDp/P6419.cpp index 4fde328..8c8ec74 100644 --- a/TangDou/Topic/HuanGenDp/P6419.cpp +++ b/TangDou/Topic/HuanGenDp/P6419.cpp @@ -11,24 +11,29 @@ void add(int a, int b, int c = 0) { e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++; } -int pos[N]; -int sz[N], f[N], g[N]; +int sz[N]; // 哪个点上有人 int len[N], id[N], slen[N]; +int f[N], g[N]; void dfs1(int u, int fa) { - if (pos[u]) sz[u] = 1; for (int i = h[u]; ~i; i = ne[i]) { int v = e[i]; if (v == fa) continue; - dfs1(v, u); - if (sz[v]) { - f[u] += f[v] + 2 * w[i]; - int now = len[v] + w[i]; - if (now >= len[u]) - slen[u] = len[u], len[u] = now, id[u] = v; - else if (now > slen[u]) - slen[u] = now; - } + dfs1(v, u); // 由底向上,先递归,再更新统计信息 + + // 如果v这个节点,及它的子节点上有人,那么需要汇总统计信息到sz[u]上去 + // 如果v上就没有人,那就不用统计了 + if (sz[v] == 0) continue; + + // ① u->v,v->u一来一回,路径翻倍 2*w[i] + // ② 所有子节点都对u有贡献,所以f[u]+ + // ③ 跑完v为根的子树后,v子树的贡献要累加到u子树上,所以f[u]+=f[v]+2*w[i] + f[u] += f[v] + 2 * w[i]; + int now = len[v] + w[i]; + if (now >= len[u]) + slen[u] = len[u], len[u] = now, id[u] = v; + else if (now > slen[u]) + slen[u] = now; sz[u] += sz[v]; } } @@ -64,11 +69,12 @@ signed main() { cin >> a >> b >> c; add(a, b, c), add(b, a, c); } - for (int i = 1; i <= m; i++) { + for (int i = 1; i <= m; i++) { // 有m个人 int x; cin >> x; - pos[x] = 1; + sz[x] = 1; // x号点上有人 } + dfs1(1, 0); g[1] = f[1]; diff --git a/TangDou/Topic/【换根DP】专题.md b/TangDou/Topic/【换根DP】专题.md index 7299d43..371e48d 100644 --- a/TangDou/Topic/【换根DP】专题.md +++ b/TangDou/Topic/【换根DP】专题.md @@ -998,7 +998,25 @@ int main() { 先放第一次$dfs$的代码: - +```cpp {.line-numbers} +void dfs1(int u, int fa) { + if (pos[u]) sz[u] = 1; + for (int i = h[u]; ~i; i = ne[i]) { + int v = e[i]; + if (v == fa) continue; + dfs1(v, u); + if (sz[v]) { + f[u] += f[v] + 2 * w[i]; + int now = len[v] + w[i]; + if (now >= len[u]) + slen[u] = len[u], len[u] = now, id[u] = v; + else if (now > slen[u]) + slen[u] = now; + } + sz[u] += sz[v]; + } +} +```