main
黄海 2 years ago
parent 6b3ea6568a
commit d8fb6c3a06

@ -1,42 +1,38 @@
#include <bits/stdc++.h> #include <bits/stdc++.h>
using namespace std; using namespace std;
const int N = 200010, M = N << 1;
#define int long long #define int long long
#define endl "\n" #define endl "\n"
const int N = 200010, M = N << 1;
int n;
// 链式前向星 // 链式前向星
int e[M], h[N], idx, w[M], ne[M]; int e[M], h[N], idx, w[M], ne[M];
void add(int a, int b, int c = 0) { void add(int a, int b, int c = 0) {
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++; e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
} }
int n; int sz[N], f[N], g[N], ans;
int f[N];
int g[N];
// 第一次dfs,向下向上,生成汇总信息
void dfs1(int u, int fa) { 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]) { for (int i = h[u]; ~i; i = ne[i]) {
int v = e[i]; int v = e[i];
if (v != fa) { if (v == fa) continue;
// 先填充子孙节点的统计信息
dfs1(v, u); dfs1(v, u);
// 利用子孙节点的统计信息汇总生成u节点的连通块节点个数统计信息 sz[u] += sz[v];
f[u] += f[v]; f[u] += f[v];
} }
} f[u] += sz[u];
} }
// 第二次dfs,向上向下
void dfs2(int u, int fa) { void dfs2(int u, int fa) {
for (int i = h[u]; ~i; i = ne[i]) { for (int i = h[u]; ~i; i = ne[i]) {
int v = e[i]; int v = e[i];
if (v != fa) { if (v == fa) continue;
g[v] = g[u] + f[1] - 2 * f[v]; g[v] = n - sz[v] + g[u] - sz[v];
dfs2(v, u); dfs2(v, u);
} }
}
} }
signed main() { signed main() {
@ -49,16 +45,10 @@ signed main() {
cin >> a >> b; cin >> a >> b;
add(a, b), add(b, a); add(a, b), add(b, a);
} }
dfs1(1, 0); dfs1(1, 0);
g[1] = f[1];
// 这是啥?
for (int i = 1; i <= n; i++) g[1] += f[i];
dfs2(1, 0); dfs2(1, 0);
int ans = 0; int ans = 0;
for (int i = 1; i <= n; i++) ans = max(ans, g[i]); for (int i = 1; i <= n; i++) ans = max(ans, g[i]);
cout << ans << endl; cout << ans << endl;
} }

@ -469,115 +469,8 @@ $O(n^2)$ ,稳稳地暴毙,然后就会自然而然地想到换根$dp$。
然后考虑父亲方向,也就是图中红圈部分对 $g[2]$ 的贡献。 然后考虑父亲方向,也就是图中红圈部分对 $g[2]$ 的贡献。
那么除了以 $2$ 号结点,与 $1$ 号结点相邻的其他子树都会对答案产生贡献,也就是说,我们只需要用以 $1$ 号结点为根时的权值减去以 那么除了以 $2$ 号结点,与 $1$ 号结点相邻的其他子树都会对答案产生贡献,也就是说,我们只需要用以 $1$ 号结点为根时的权值减去以 $2$ 为根的子树的贡献即可,也就是 $g[1]-f[2]-sz[2]$ 。
$2$ 为根的子树的贡献即可,也就是 $g[1]-f[2]-sz[2]$ 。
不要忘了加上
<EFBFBD>
n ,也就是初始的白色连通块大小。
综合一下上述两种方向的贡献,可以得到:
<EFBFBD>
2
=
(
<EFBFBD>
2
<EFBFBD>
<EFBFBD>
<EFBFBD>
2
)
+
(
<EFBFBD>
1
<EFBFBD>
2
<EFBFBD>
<EFBFBD>
<EFBFBD>
2
)
+
<EFBFBD>
=
<EFBFBD>
1
+
<EFBFBD>
<EFBFBD>
<EFBFBD>
<EFBFBD>
2
×
2
g
2
=(f
2
siz
2
)+(g
1
f
2
siz
2
)+n=g
1
+nsiz
2
×2 。
推广到所有结点,就可以得到:
<EFBFBD>
<EFBFBD>
=
<EFBFBD>
<EFBFBD>
<EFBFBD>
<EFBFBD>
<EFBFBD>
<EFBFBD>
<EFBFBD>
+
<EFBFBD>
<EFBFBD>
<EFBFBD>
<EFBFBD>
<EFBFBD>
×
2
g
u
=g
father
u
+nsiz
u
×2
然后跑两遍 dfs 就愉快的解决啦。
#### [$CF1324F$.$Maximum$ $White$ $Subtree$](https://www.luogu.com.cn/problem/CF1324F) #### [$CF1324F$.$Maximum$ $White$ $Subtree$](https://www.luogu.com.cn/problem/CF1324F)

Loading…
Cancel
Save