zoukankan      html  css  js  c++  java
  • bzoj2638 黑白染色

    Description

     你有一个n*m的矩形,一开始所有格子都是白色,然后给出一个目标状态的矩形,有的地方是白色,有的地方是黑色,你每次可以选择一个连通块(四连通块,且不要求颜色一样)进行染色操作(染成白色或者黑色)。问最少操作次数。

    Input

      第一行两个数n,m表示矩形大小。
      接下来n行描述目标状态,每行m个字符,’W’表示白色,’B’表示黑色。

    Output

      一行一个整数表示操作数。
    将同色方块缩点建出二分图
    枚举每个点为根求bfs树
    按深度从深至浅顺序染色
    树的深度-(最深叶节点为白色?1:0)为以这个点为中心染色的最少操作次数
    #include<cstdio>
    int n,m;
    char s[56][56],col[3000];
    int id[56][56],idp=0;
    int es[20050],enx[20050],e0[3000],l[3000],q[3000],ep=2,ql,qr,mx,ans;
    void dfs(int x,int y,int c){
        if(id[x][y]||s[x][y]!=c)return;
        id[x][y]=idp;
        dfs(x-1,y,c);
        dfs(x+1,y,c);
        dfs(x,y-1,c);
        dfs(x,y+1,c);
    }
    void adde(int a,int b){
        es[ep]=b;enx[ep]=e0[a];e0[a]=ep++;
        es[ep]=a;enx[ep]=e0[b];e0[b]=ep++;
    }
    int main(){
        scanf("%d%d",&n,&m);
        ans=n*m;
        for(int i=1;i<=n;i++)scanf("%s",s[i]+1);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(!id[i][j]){
                    col[++idp]=s[i][j];
                    dfs(i,j,col[idp]);
                }
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<m;j++){
                if(id[i][j]!=id[i][j+1])adde(id[i][j],id[i][j+1]);
            }
        }
        for(int i=1;i<n;i++){
            for(int j=1;j<=m;j++){
                if(id[i][j]!=id[i+1][j])adde(id[i][j],id[i+1][j]);
            }
        }
        for(int i=1;i<=idp;i++){
            for(int j=1;j<=idp;j++)l[j]=0;
            l[i]=1;
            ql=qr=mx=0;
            q[qr++]=i;
            while(ql!=qr){
                int w=q[ql++];
                if(l[w]>mx)mx=l[w];
                for(int e=e0[w];e;e=enx[e]){
                    int u=es[e];
                    if(!l[u]){
                        l[u]=l[w]+1;
                        q[qr++]=u;
                    }
                }
            }
            if(col[i]=='W'&&(mx&1))--mx;
            if(col[i]=='B'&&!(mx&1))--mx;
            if(mx<ans)ans=mx;
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    JavaScript日期加减
    javascript乘除算法解决浮点精度
    npm的chalk包的使用
    npm模块copy-to-clipboard复制内容到剪切板
    BeeFramework 系列一 安装篇(Arc)
    CocoaPods详解之----使用篇
    ObjectiveC 深浅拷贝学习
    unity项目针对IOS及Android平台的音频压缩格式
    通过IP地址定位准确的地理位置
    Unity 通过代码简单实现文理的灰化显示
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5532844.html
Copyright © 2011-2022 走看看