From d8fb6c3a0610bb6bca8b269ca3e9a7aa0c797b99 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 10:01:53 +0800 Subject: [PATCH] 'commit' --- TangDou/Topic/HuanGenDp/CF1187E.cpp | 40 ++++----- TangDou/Topic/【换根】dfs专题.md | 111 +------------------------ 2 files changed, 17 insertions(+), 134 deletions(-) diff --git a/TangDou/Topic/HuanGenDp/CF1187E.cpp b/TangDou/Topic/HuanGenDp/CF1187E.cpp index 17375c0..fb094f2 100644 --- a/TangDou/Topic/HuanGenDp/CF1187E.cpp +++ b/TangDou/Topic/HuanGenDp/CF1187E.cpp @@ -1,41 +1,37 @@ #include using namespace std; -const int N = 200010, M = N << 1; #define int long long #define endl "\n" +const int N = 200010, M = N << 1; + +int n; + // 链式前向星 int e[M], h[N], idx, w[M], ne[M]; void add(int a, int b, int c = 0) { e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++; } -int n; -int f[N]; -int g[N]; +int sz[N], f[N], g[N], ans; -// 第一次dfs,向下向上,生成汇总信息 void dfs1(int u, int fa) { - f[u] = 1; // 以u为根的子树大小,初始时有u一个节点,sz[u]=1 + sz[u] = 1; for (int i = h[u]; ~i; i = ne[i]) { int v = e[i]; - if (v != fa) { - // 先填充子孙节点的统计信息 - dfs1(v, u); - // 利用子孙节点的统计信息,汇总生成u节点的连通块节点个数统计信息 - f[u] += f[v]; - } + if (v == fa) continue; + dfs1(v, u); + sz[u] += sz[v]; + f[u] += f[v]; } + f[u] += sz[u]; } - -// 第二次dfs,向上向下 void dfs2(int u, int fa) { for (int i = h[u]; ~i; i = ne[i]) { int v = e[i]; - if (v != fa) { - g[v] = g[u] + f[1] - 2 * f[v]; - dfs2(v, u); - } + if (v == fa) continue; + g[v] = n - sz[v] + g[u] - sz[v]; + dfs2(v, u); } } @@ -49,16 +45,10 @@ signed main() { cin >> a >> b; add(a, b), add(b, a); } - dfs1(1, 0); - - // 这是啥? - for (int i = 1; i <= n; i++) g[1] += f[i]; - + g[1] = f[1]; dfs2(1, 0); - int ans = 0; for (int i = 1; i <= n; i++) ans = max(ans, g[i]); - cout << ans << endl; } \ No newline at end of file diff --git a/TangDou/Topic/【换根】dfs专题.md b/TangDou/Topic/【换根】dfs专题.md index ebfb313..71ffe74 100644 --- a/TangDou/Topic/【换根】dfs专题.md +++ b/TangDou/Topic/【换根】dfs专题.md @@ -469,115 +469,8 @@ $O(n^2)$ ,稳稳地暴毙,然后就会自然而然地想到换根$dp$。 然后考虑父亲方向,也就是图中红圈部分对 $g[2]$ 的贡献。 -那么除了以 $2$ 号结点,与 $1$ 号结点相邻的其他子树都会对答案产生贡献,也就是说,我们只需要用以 $1$ 号结点为根时的权值减去以 -$2$ 为根的子树的贡献即可,也就是 $g[1]-f[2]-sz[2]$ 。 - -不要忘了加上 -� -n ,也就是初始的白色连通块大小。 - -综合一下上述两种方向的贡献,可以得到: -� -2 -= -( -� -2 -− -� -� -� -2 -) -+ -( -� -1 -− -� -2 -− -� -� -� -2 -) -+ -� -= -� -1 -+ -� -− -� -� -� -2 -× -2 -g -2 -​ - =(f -2 -​ - −siz -2 -​ - )+(g -1 -​ - −f -2 -​ - −siz -2 -​ - )+n=g -1 -​ - +n−siz -2 -​ - ×2 。 - -推广到所有结点,就可以得到: - -� -� -= -� -� -� -� -ℎ -� -� -� -+ -� -− -� -� -� -� -× -2 -g -u -​ - =g -father -u -​ - - - +n−siz -u -​ - ×2 -然后跑两遍 dfs 就愉快的解决啦。 +那么除了以 $2$ 号结点,与 $1$ 号结点相邻的其他子树都会对答案产生贡献,也就是说,我们只需要用以 $1$ 号结点为根时的权值减去以 $2$ 为根的子树的贡献即可,也就是 $g[1]-f[2]-sz[2]$ 。 + #### [$CF1324F$.$Maximum$ $White$ $Subtree$](https://www.luogu.com.cn/problem/CF1324F)