首页 > 其他分享 >CF1592F2-Alice and Recoloring 2-分析、二分图

CF1592F2-Alice and Recoloring 2-分析、二分图

时间:2024-09-26 22:13:01浏览次数:1  
标签:return int 矩阵 rep CF1592F2 Alice vector ans Recoloring

link:https://codeforces.com/contest/1592/problem/F2
题意:给定一个 \(n\) 行 \(m\) 列的目标矩阵,矩阵元素只有 W 或 B ,并且你有一个初始矩阵,元素全为 W 。
现在你可以矩阵实施以下操作:

  • 使用一块钱,选定一个包含 \((1,1)\) 的子矩阵,把矩阵中的元素全部反转( W 变 B , B 变 W )。
  • 使用三块钱,选定一个包含 \((n,1)\) 的子矩阵,把矩阵中的元素全部反转。
  • 使用四块钱,选定一个包含 \((1,m)\) 的子矩阵,把矩阵中的元素全部反转。
  • 使用两块钱,选定一个包含 \((n,m)\) 的子矩阵,把矩阵中的元素全部反转。
    现在需要你求出把初始矩阵变为目标矩阵最少需要几块钱。

\(1\leq n,m\leq 500\).


首先四个操作中有一些直接是没有用的:

  • 右上角花费4元的操作,可以用2次左上角1元解决
  • 左下角花费3元的操作,也可以用2次左上角1元解决
  • 那么只剩下左上和右下角的
    操作相当于区间(二维的)异或,考虑做一个差分数组 \(s_{i,j}=a_{i,j}\oplus a_{i,j+1}\oplus a_{i_+1,j}\oplus a_{i+1,j+1}\)(网格外的一律当做单位元 \(0\)),那么操作1相当于单点修改 \(s_{i,j}\),右下角相当于修改四个位置 \(s_{i-1,j-1},s_{n,j-1},s_{i-1,m},s_{n,m}\)

那么就变成:

  • 花费1块钱做单点修改
  • 花费2块钱可以修改4个特定的位置
    对于这 \(4\) 个位置注意到:
  • (1)一行至多被操作一次,否则 \(s_{n,m},s_{i-1,m}\) 相当于不变,每次只修改 \(2\) 个位置,可以直接用操作1代替
  • (2)一个位置如果要修改,必须 \(s_{i-1,j-1},s_{i-1,m},s_{n,j-1}\) 都是 \(1\) ,否则如果有一个不是 \(1\),操作完了还要花钱把它改回来,花费了 \(2+1=3\) 块钱,用操作1也是同样的花费

因此对于所有满足 \(s_{i-1,j-1},s_{n,j-1},s_{i-1,m}\) 都是 \(1\) 的位置 \((i,j)\) 连一条左边 \(i\) 到右边 \(j\) 的边(网格图每行每列经典的二分图),相当于每行每列至多选一次,并且只有满足条件的可能被选上。

正常用操作1花费是所有\(s_{i,j}=1\) 的个数,对于操作 \(2\) 先不考虑最右下角的点,那么相当于用2块钱改了3个点,少一块钱,因此答案=\(s-\)二分图的最大匹配。
最后考察右下角:看最大流的奇偶性,如果同奇偶性就不用额外花费,否则答案+1

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define endl '\n'
#define fastio ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
using namespace std;

template<class T>
struct Dinic{//ind from 0 to n-1
    struct Edge{
        int to;T cap;
        Edge(int to,T cap):to(to),cap(cap){}
    };
    int n;
    vector<Edge> E;
    vector<vector<int>> G;
    vector<int> cur,h;

    Dinic(int n=0){init(n);}
    void init(int n){
        this->n=n;
        E.clear();
        cur.resize(n);
        h.resize(n);
        G.assign(n,{});
    }
    void addEdge(int u,int v,T c){
        G[u].push_back(E.size());E.emplace_back(v,c);
        G[v].push_back(E.size());E.emplace_back(u,0);
    }
    bool bfs(int s,int t){
        h.assign(n,-1);
        queue<int> que;
        h[s]=0;
        que.push(s);
        while(!que.empty()){
            const int u=que.front();
            que.pop();
            for(auto i:G[u]){
                auto [v,c]=E[i];
                if(c>0&&h[v]==-1){
                    h[v]=h[u]+1;
                    if(v==t)return true;
                    que.push(v);
                }
            }
        }
        return false;
    }
    T dfs(int u,int t,T f){
        if(u==t)return f;
        auto r=f;
        for(int &i=cur[u];i<(int)G[u].size();i++){
            const int j=G[u][i];
            auto [v,c]=E[j];
            if(c>0&&h[v]==h[u]+1){
                auto a=dfs(v,t,std::min(r,c));
                E[j].cap-=a;
                E[j^1].cap+=a;
                r-=a;
                if(r==0)return f;
            }
        }
        return f-r;
    }
    T work(int s,int t){
        T ans=0;
        while(bfs(s,t)){
            cur.assign(n,0);
            ans+=dfs(s,t,std::numeric_limits<T>::max());
        }
        return ans;
    }
    vector<bool> minCut(){
        vector<bool> c(n);
        rep(i,0,n-1)c[i]=(h[i]!=-1);
        return c;
    }
    struct scheme{
        int u,v;
        T cap,flow;
    };
    vector<scheme> get(){
        vector<scheme> ans;
        for(int i=0;i<(int)E.size();i+=2)
            ans.push_back({E[i+1].to,E[i].to,E[i].cap+E[i+1].cap,E[i+1].cap});
        return ans;
    }
};
int main(){
    fastio;
    int n,m;
    cin>>n>>m;
    auto a=vector<vector<int>>(n+2,vector<int>(m+2));
    auto s=vector<vector<int>>(n+2,vector<int>(m+2));
    rep(i,1,n){
        string s;
        cin>>s;
        rep(j,1,m)a[i][j]=(s[j-1]=='B');
    }
    rep(i,1,n)rep(j,1,m)s[i][j]=(a[i][j]^a[i+1][j]^a[i][j+1]^a[i+1][j+1]);
    
    //[1,n],[n+1,n+m]
    int S=n+m+1,T=n+m+2;
    Dinic<int> flow(T+1);
    int ans=0;
    rep(i,1,n)rep(j,1,m)ans+=s[i][j];
    rep(i,1,n-1)rep(j,1,m-1)if(s[i][j]&&s[n][j]&&s[i][m])flow.addEdge(i,j+n,1);
    rep(i,1,n)flow.addEdge(S,i,1);
    rep(j,1,m)flow.addEdge(j+n,T,1);
    int f=flow.work(S,T);
    ans-=s[n][m];
    ans=ans-f+((f&1)^s[n][m]);
    cout<<ans;
    return 0;
}

标签:return,int,矩阵,rep,CF1592F2,Alice,vector,ans,Recoloring
From: https://www.cnblogs.com/yoshinow2001/p/18434553

相关文章

  • 配置alice
    配置alicehttps://github.com/alist-org/alist/release#下载alist压缩包alist-windows-amd64.zip下载自己对应的版本windows64版本#下载aria2chttps://github.com/aria2/aria2/releases右键点击“此电脑”,选择“属性”。点击“高级系统设置”,然后点击“环境变量”。......
  • P11072 Alice and Bob 题解
    简单博弈题。先说结论,如果存在\(a_i=0\)使得\(1\lei\lea_1\)的话,那么先手必胜,否则后手必胜。若满足上述条件显然先手必胜,将\(0\)搞到第一个就行。否则Alice每操作一次,如果操作后满足了上述条件,那么Bob赢,否则Bob只要不动就行。但是下一轮Alice必须动,要不然两......
  • Alice和Bob的爱恨情仇(lanqiao OJ 3865)
    问题如下(附链接):Alice和Bob的爱恨情仇题解代码如下:#include<bits/stdc++.h>usingnamespacestd;intmain(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);intn,k;cin>>n>>k;intans=0;for(inti=0;i<n;i++){intx;cin>>......
  • leetcode线段树(2940. 找到 Alice 和 Bob 可以相遇的建筑)
    前言经过前期的基础训练以及部分实战练习,粗略掌握了各种题型的解题思路。现阶段开始专项练习。描述给你一个下标从 0 开始的正整数数组 heights ,其中 heights[i] 表示第 i 栋建筑的高度。如果一个人在建筑 i ,且存在 i<j 的建筑 j 满足 heights[i]<heig......
  • 力扣刷题之2940.找到Alice和Bob可能相遇的建筑
    题干描述给你一个下标从 0 开始的正整数数组 heights ,其中 heights[i] 表示第 i 栋建筑的高度。如果一个人在建筑 i ,且存在 i<j 的建筑 j 满足 heights[i]<heights[j] ,那么这个人可以移动到建筑 j 。给你另外一个数组 queries ,其中 queries[i]=[......
  • 题解 - Alice
    题目描述Alice和Bob在玩游戏,游戏规则如下:有两堆石子,每堆石子有非负整数个Alice与Bob轮流操作,Alice先手,每次可以从任意一堆石子中取出若干个取出的石子个数应满足为另一堆石子个数的因数(此处规定任何数均为0的因数)将石子取完的玩家获胜给定一个初始状态,现......
  • CF585C Alice, Bob, Oranges and Apples
    感觉和辗转相除相似,考虑证明正确性设当前Alice的橙子、苹果数为\(a_0,a_1\),Bob同理,考虑构造状态矩阵\(\begin{pmatrix}a_0&b_0\\a_1&b_1\\\end{pmatrix}\),那么初始状态\(I\)为\(\begin{pmatrix}1&0\\0&1\\\end{pmatrix}\),那么\(A\)操作相当于\(\times......
  • 题解:CodeForces 346A Alice and Bob[博弈/数论]
    CodeForces346AA.AliceandBobtimelimitpertest2secondsmemorylimitpertest256megabytesinputstandardinputoutputstandardoutputItissoboringinthesummerholiday,isn'tit?SoAliceandBobhaveinventedanewgametoplay.Therulesa......
  • 2024-06-15:用go语言,Alice 和 Bob 在一个环形草地上玩一个回合制游戏。 草地上分布着一
    2024-06-15:用go语言,Alice和Bob在一个环形草地上玩一个回合制游戏。草地上分布着一些鲜花,其中Alice到Bob之间顺时针方向有x朵鲜花,逆时针方向有y朵鲜花。游戏规则如下:1.游戏从Alice开始。2.每个回合中,当前玩家必须选择顺时针或逆时针,并在所选方向上摘取一朵鲜花。......
  • Alice in wonderland
    Hello.ThisisthestoryofanordinarygirlcalledAlice.Ourstorybeginsonanordinarysummer’sday.Let’smeetAlice:heresheis,sheis,sittingnexttotheriverwithhersisteronaveryhotsummer’safternoon.Hersisterisreadingabook,andwithno......