https://www.luogu.com.cn/problem/CF1592F2
做完F1,然后用1的结论来思考。
场上推了几个性质。首先op4的操作行列必然两两不同,所以op4最多 max ( n , m ) \max(n,m) max(n,m) 次。然后手玩发现只有除 ( n , m ) (n,m) (n,m) 的三个格子都为1,op4才有意义。
然后猜了个网络流。每个点如果满足条件,就向行列连边。
但这样显得我非常愚蠢。
因为中间的点完全没用,直接行向列连边就变成二分图了…
auto calc = [&] (int x, int y) -> int {return a[x][y]^a[x+1][y]^a[x][y+1]^a[x+1][y+1]; }; mf_graph<int>G(N*N); n=read(); m=read(); for(i=1; i<=n; ++i) {scanf("%s", str+1); for(j=1; j<=m; ++j) if(str[j]=='B') a[i][j]=1; }for(i=n; i>=1; --i) for(j=m; j>=1; --j) {v[i][j]=calc(i, j); sum+=v[i][j]; }S=n+m+1; T=S+1; for(i=1; i<n; ++i) if(v[i][m]) G.add_edge(S, i, 1); for(i=1; i<m; ++i) if(v[n][i]) G.add_edge(i+n, T, 1); for(i=1; i<n; ++i)for(j=1; j<m; ++j) if(v[i][j] && v[n][j] && v[i][m]) G.add_edge(i, j+n, 1); k=G.flow(S, T); p=v[i][j]; v[i][j]^=(k&1);
// printf("%d %d\n", sum, k); ans=min(sum, sum-k-p+v[i][j]); if(v[i][j] && k) ans=min(ans, sum-(k-1)); printf("%d", ans);