CF1375G Tree Modification
\(\mathtt{Description}\)
给 \(n\) 个点的树,可以进行如下操作:
选择三个点 \(a,b,c\),要求 \(a,b\) 相邻,\(b,c\) 相邻,断掉 \(a\) 的所有边,并连到 \(c\) 上,将 \(a,c\) 连边。
求最小操作次数使得该树变成菊花图。
\(n\le2\times 10^5\)
\(\mathtt{Solution}\)
考虑这个魔性的修改带来的效果。
对树进行黑白染色(即 \(x\) 节点的父亲和儿子都是与其相反的颜色)并动态维护颜色,发现一次操作之后,只会改变 \(a\) 的颜色。
而菊花图的条件则是只有一个点是黑或白,所以答案就是 \(\min(\text{white,black)}-1\)(即至修改黑点颜色或至修改白点颜色)。
\(\mathtt{Code}\)
#include <cstdio>
#include <algorithm>
const int N = 2e5 + 5 ;
int n,cnt;
int head[N],to[N << 1],nxt[N << 1],clr[N] ;
void add(int u,int v) {
to[++cnt] = v,nxt[cnt] = head[u],head[u] = cnt ;
}
void dfs(int x,int f) {
clr[x] = clr[f] ^ 1;
for (int i = head[x]; i; i = nxt[i]){
int v = to[i] ;
if (v == f) continue ;
dfs(v,x) ;
}
}
int main() {
scanf("%d",&n) ;
for (int i = 1,u,v; i < n; ++i)
scanf("%d%d",&u,&v),add(u,v),add(v,u) ;
dfs(1,0) ;
int w = 0,b = 0 ;
for (int i = 1; i <= n; ++i)
w += clr[i],b += clr[i] ^ 1;
printf("%d",std::min(w,b) - 1) ;
return 0 ;
}

浙公网安备 33010602011771号