• 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;
    }
  • 相关阅读:
    投稿007期|令人震惊到发指的PyObject对象代码设计之美
    使用OpenCV通过摄像头捕获实时视频并探测人脸
    洛谷 P1259【黑白棋子的移动】
    入门OJ 1281【营救(save)】
    入门OJ 3204【射击】
    POJ 3126【长度为素数的路径个数】
    POJ 1980【Unit Fraction Partition】
    洛谷 P2374【搬运工】
    【常用算法总结——记忆化搜索】
    P3052 [USACO12MAR]【摩天大楼里的奶牛(Cows in a Skyscraper)】
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5532844.html
Copyright © 2020-2023  润新知