diff --git a/TangDou/Topic/HuanGenDp/CF1324F.cpp b/TangDou/Topic/HuanGenDp/CF1324F.cpp index ee6a0e6..3100dcd 100644 --- a/TangDou/Topic/HuanGenDp/CF1324F.cpp +++ b/TangDou/Topic/HuanGenDp/CF1324F.cpp @@ -8,26 +8,31 @@ void add(int a, int b, int c = 0) { e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++; } -int n, c[N], f1[N], f2[N]; +int n, c[N]; + +// 设白点个数cnt1,黑点个数cnt2, f[u]:以u为根的子树中,cnt1-cnt2的最大值 +int f1[N], f2[N]; void dfs1(int u, int fa) { if (c[u]) - f1[u] = 1; + f1[u] = 1; // 如果u是白色则cnt1=1,那么目前黑色数量cnt2=0,cnt1-cnt2是固定值=1 else - f1[u] = -1; + f1[u] = -1; // 如果u是黑色则cnt1=0,那么目前黑色数量cnt2=1,cnt1-cnt2是固定值=0-1=-1 for (int i = h[u]; ~i; i = ne[i]) { int v = e[i]; if (v == fa) continue; dfs1(v, u); - f1[u] += max(f1[v], 0); + f1[u] += max(f1[v], 0); // 为了贪图cnt1-cnt2的最大值,那么对结果有贡献的就竞争一下,如果都小于0了,就退出评比 } } +// 换根dp void dfs2(int u, int fa) { for (int i = h[u]; ~i; i = ne[i]) { int v = e[i]; if (v == fa) continue; + // 本题的核心:递推式 f2[v] = max(f2[u] + f1[u] - max(f1[v], 0), 0); dfs2(v, u); } @@ -37,18 +42,18 @@ int main() { memset(h, -1, sizeof h); cin >> n; - for (int i = 1; i <= n; i++) cin >> c[i]; + for (int i = 1; i <= n; i++) cin >> c[i]; // 每个节点都有自己的颜色c[i] - for (int i = 1; i <= n - 1; i++) { + for (int i = 1; i < n; i++) { // n-1条边 int a, b; cin >> a >> b; add(a, b), add(b, a); } - - dfs1(1, 1); - - dfs2(1, 1); + // 第一次dfs + dfs1(1, 0); + // 第二次dfs,换根 + dfs2(1, 0); + // 输出 for (int i = 1; i <= n; i++) printf("%d ", f1[i] + f2[i]); - return 0; } diff --git a/TangDou/Topic/【换根】dfs专题.md b/TangDou/Topic/【换根】dfs专题.md index 31cbce2..287a149 100644 --- a/TangDou/Topic/【换根】dfs专题.md +++ b/TangDou/Topic/【换根】dfs专题.md @@ -571,6 +571,20 @@ signed main() { ![](https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/BlogImages/202401100839763.png) +我们在代码中将黑色记为$-1$,白色记为$1$ +> **注**:这个转化很有用,因为$cnt_1-cnt_2$是所求: +> - 如果是白色,则$cnt_1=1,cnt_2=0$,此时$cnt_1-cnt_2=1-0=1$ +> - 如果是黑色,则$cnt_1=0,cnt_2=1$,此时$cnt_1-cnt_2=0-1=-1$ +> 所以,我们可以理解为黑色记为$-1$,白色记为$1$ + +很显然: +$$\large f[u]=a_u+\sum_{v \in son_u}max(f_v,0)$$ + +$a_i$就是$i$号点的颜色。 +那么可以根据上文的讲解得出: +$$\large ans_i=f_i+max(ans_{fa}-max(f_i,0),0)$$ + + [USACO12FEB]Nearby Cows G [COCI2014-2015#1]Kamp