CF1592F2 Alice and Recoloring 2 题解
操作 $2,3$ 可以用 $1,4$ 容斥,所以没用。
设 $b_{i,j}=a_{i,j}\oplus a_{i+1,j}\oplus a_{i,j+1}\oplus a_{i+1,j+1}$,
则操作 $1$ 翻转 $(1,1)$ 到 $(i,j)$ 的矩阵等价于 $b_{i,j}\gets b_{i,j}\oplus 1$,
操作 $4$ 翻转 $(i,j)$ 到 $(n,m)$ 的矩阵等价于 $b_{n,m}\gets b_{n,m}\oplus 1,b_{i-1,m}\gets b_{i-1,m}\oplus 1,b_{n,j-1}\gets b_{n.j-1}\oplus 1,b_{i-1,j-1}\gets b_{i-1,j-1}\oplus 1$。
注意到所有操作 $4$ 的 $i$ 一定互不相同且 $j$ 一定互不相同,否则不如操作 $1$。
则问题转化为求最多能找出多少 $(i,j)$ 满足 $i$ 互不相同,$j$ 互不相同且 $b_{i,j}=b_{i,m}=b_{n,j}=1$。
以 $i\in[1,n)$ 为左半部,$j\in[1,m)$ 为右半部建二分图,存在 $i\to j$ 当且仅当 $b_{i,j}=b_{i,m}=b_{n,j}=1$,则该图的最大匹配即为操作 $4$ 的个数 $p$。
一次操作 $4$ 可以省一次操作 $1$,所以这些操作 $4$ 的贡献是 $-p$。
注意 $p$ 为奇数时要特判 $b_{n,m}$ 的值,
若 $b_{n,m}=0$ 则经过这些操作 $4$ 后 $b_{n,m}$ 变为 $1$,需要一个额外的操作 $1$。
若 $b_{n,m}=1$ 则经过这些操作 $4$ 后 $b_{n,m}$ 变为 $0$,可以省一个操作 $1$。
#include <queue>
#include <cstdio>
#include <cstring>
using namespace std;
struct E{int v, w, t;}e[250050];
int n, m, r, p, c = 1, s, t, d[1050], g[1050], h[1050];
bool a[550][550], b[550][550];char z;queue<int> q;
void A(int u, int v, int w) {e[++c] = {v, w, h[u]};h[u] = c;}
bool B()
{
memset(d, 0, sizeof d);d[s] = 1;q.push(s);while(!q.empty())
{
int u = q.front();q.pop();g[u] = h[u];for(int i = h[u], v;i;i =
e[i].t) if(e[i].w && !d[v = e[i].v]) d[v] = d[u] + 1, q.push(v);
}
return d[t];
}
int D(int u, int f)
{
if(u == t) return f;
int k, q = 0;
for(int i = g[u], v;i && f;i = e[i].t)
{
g[u] = i;
if(e[i].w && d[v = e[i].v] == d[u] + 1)
k = D(v, min(e[i].w, f)), e[i].w -= k, e[i ^ 1].w += k, q += k, f -= k;
}
return q;
}
int main()
{
scanf("%d%d", &n, &m);t = n + m;
for(int i = 1;i <= n;++i)
for(int j = 1;j <= m;++j)
scanf(" %c", &z), a[i][j] = z == 'B';
for(int i = 1;i <= n;++i)
for(int j = 1;j <= m;++j)
b[i][j] = a[i][j] ^ a[i + 1][j] ^ a[i][j + 1] ^ a[i + 1][j + 1];
for(int i = 1;i <= n;++i)
for(int j = 1;j <= m;++j)
r += b[i][j];
for(int i = 1;i < n;++i)
for(int j = 1;j < m;++j)
if(b[i][j] && b[i][m] && b[n][j])
A(i, j + n, 1), A(j + n, i, 0);
for(int i = 1;i < n;++i) A(0, i, 1), A(i, 0, 0);
for(int i = 1;i < m;++i) A(i + n, t, 1), A(t, i + n, 0);
while(B()) p += D(0, 1e9);r -= p;
r -= b[n][m] && p & 1;
r += !b[n][m] && p & 1;
return !printf("%d", r);
}

浙公网安备 33010602011771号