[CF1592F2] Alice and Recoloring 2
操作 2 和 3 可以用另两个代替,没有任何用。
设 W
表示 \(t_{i,j}=0\),B
表示 \(t_{i,j}=1\)
考虑差分。设 \(t_{i,j}=s_{i,j}\oplus s_{i+1,j}\oplus s_{i,j+1}\oplus s_{i+1,j+1}\),那么目标变为把 $t4 数组清0
那么操作 1 是把单点翻转,操作 4 是对于一个 \(x,y(x<n,y<m)\),翻转 \((n,m),(x,y),(x,m),(n,y)\)
那么操作4有用当且仅当 \(t_{x,y},t_{x,m},t_{n,y}\) 都为 1。
然后每个 \(x\) 和 \(y\) 只能用一次,所以可以跑一个二分图匹配。
判断一下 \((n,m)\) 要不要操作。
// LUOGU_RID: 139138753
#include<bits/stdc++.h>
using namespace std;
const int N=505;
int n,m,t[N][N],ans,v[N],p[N],s[N][N],g[N][N];
char str[N];
int dfs(int x,int y)
{
for(int i=1;i<m;i++)
{
if(g[x][i]&&v[i]^y)
{
v[i]=y;
if(!p[i]||dfs(p[i],y))
return p[i]=x,1;
}
}
return 0;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%s",str+1);
for(int j=1;j<=m;j++)
t[i][j]=str[j]=='B';
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
s[i][j]=t[i][j]^t[i+1][j]^t[i+1][j+1]^t[i][j+1],ans+=s[i][j];
for(int i=1;i<n;i++)
for(int j=1;j<m;j++)
g[i][j]=s[n][j]&&s[i][m]&&s[i][j];
int c=0;
for(int i=1,k;i<=n;i++)
k=dfs(i,i),ans-=k,c+=k;
ans-=s[n][m];
if(c&1^s[n][m])
ans++;
printf("%d\n",ans);
}