zoukankan      html  css  js  c++  java
  • cf1592F2. Alice and Recoloring 2

    题目描述

    题解

    左下角和右上角操作没有用,只剩右下角和左上角的操作。

    这步很妙:设 $a_{i,j}=(ch_{i,j}=='B'),b_{i,j}=a_{i,j}\ \text{xor}\ a_{i+1,j}\ \text{xor}\ a_{i,j+1}\ \text{xor}\ a_{i+1,j+1}$ ,那么左上角操作相当于反转 $a_{i,j}$ ,右下角操作相当于反转 $a_{i,j},a_{i,m},a_{n,j},a_{n,m}$ 。

    因此,如果对 $(x,y_1),(x,y_2)$ 都进行右下角操作是不优的。而且,如果 $a_{i,j},a_{i,m},a_{n,j}$ 不同时为 $1$ ,那么进行右下角操作也是不优的。

    因此,我们设 $n-1$ 个点代表行, $m-1$ 个点代表列,然后如果 $a_{i,j},a_{i,m},a_{n,j}$ 同时为 $1$ 就连边,跑最大二分图匹配即可。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e6+5;
    int n,m,t=1,hd[N],V[N],W[N],nx[N],ans,d[N],cur[N],S,T,a[505][505];
    char ch[505][505];
    void add(int u,int v,int w){
        nx[++t]=hd[u];V[hd[u]=t]=v;W[t]=w;
    }
    void ins(int u,int v,int w){
        add(u,v,w);add(v,u,0);
    }
    queue<int>q;
    bool bfs(){
        for (int i=1;i<=T;i++) d[i]=-1;
        d[S]=0;q.push(S);
        for (;!q.empty();){
            int u=q.front();q.pop();
            for (int i=hd[u];i;i=nx[i])
                if (W[i] && !~d[V[i]])
                    d[V[i]]=d[u]+1,q.push(V[i]);
        }
        return d[T]!=-1;
    }
    int dfs(int u,int w){
        if (u==T) return w;
        int s=0,v;
        for (int &i=cur[u];i;i=nx[i]){
            if (W[i] && d[V[i]]==d[u]+1 && (v=dfs(V[i],min(w,W[i]))))
                w-=v,W[i]-=v,W[i^1]+=v,s+=v;
            if (!w) break;
        }
        return s;
    }
    int main(){
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++)
            scanf("%s",ch[i]+1);
        for (int i=1;i<=n;i++)
            for (int j=1;j<=m;j++)
                a[i][j]=(ch[i][j]=='B')^(ch[i][j+1]=='B')^(ch[i+1][j]=='B')^(ch[i+1][j+1]=='B');
        for (int i=1;i<n;i++)
            for (int j=1;j<m;j++)
                if (a[i][j] && a[i][m] && a[n][j])
                    ins(i,j+n-1,1);
        S=n+m-1;T=S+1;
        for (int i=1;i<n;i++) ins(S,i,1);
        for (int i=1;i<m;i++) ins(i+n-1,T,1);
        while(bfs()){
            for (int i=1;i<=T;i++) cur[i]=hd[i];
            ans+=dfs(S,1e9);
        }
        a[n][m]^=(ans&1);ans=-ans;
        for (int i=1;i<=n;i++)
            for (int j=1;j<=m;j++)
                ans+=a[i][j];
        printf("%d\n",ans);
        return 0;
    }
  • 相关阅读:
    pandas Series和DataFrame数据类型
    numpy 统计函数与随机数
    numpy 索引
    numpy 数组复制与广播机制
    numpy 合并数组和切割数组
    numpy 添加删除去重及形状变换
    项目导入问题---讨厌的红色感叹号
    SpringMVC框架-----概述(2)
    SpringMVC框架-----概述(1)
    SpringBoot框架----概述(1)
  • 原文地址:https://www.cnblogs.com/xjqxjq/p/15542439.html
Copyright © 2011-2022 走看看