CODEVS1049 棋盘染色

Posted 小时のblog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CODEVS1049 棋盘染色相关的知识,希望对你有一定的参考价值。

题目大意:01矩阵,1表示黑色,0表示白色,求将白色染成黑色最少的次数

使黑色成为一整个联通块。

题解:

搜索bfs 90...

dfs判断连通

技术分享
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;

int cnt,ans,flag;
int map[7][7],vis[7][7];
int mx[4]={1,0,0,-1},
    my[4]={0,-1,1,0};
string s;

struct node{
    int x,y;
}a[30];

inline void find(int x,int y){
    for(int i=0;i<4;i++){
        int xx=x+mx[i],yy=y+my[i];
        if(map[xx][yy]&&!vis[xx][yy]){
            vis[xx][yy]=true;
            find(xx,yy);
        }
    }
}

bool check(){
    int gg=0;
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=5;i++)
     for(register int j=1;j<=5;j++)
      if(!vis[i][j]&&map[i][j]){
          gg++;if(gg>1)return false;
        vis[i][j]=true;find(i,j);
      }
    return true;
}

void dfs(int x,int sum){
    if(x==cnt+1){
        if(check())
        ans=min(ans,sum);
        return;
    }
    map[a[x].x][a[x].y]=1;    
    dfs(x+1,sum+1);
    map[a[x].x][a[x].y]=0;
    dfs(x+1,sum);
}

int main(){
    for(int i=1;i<=5;i++){
        cin>>s;
        for(int j=1;j<=5;j++){
            map[i][j]=s[j-1]-0;
            if(!map[i][j])a[++cnt].x=i,a[cnt].y=j;
        } 
    }
    ans=5*5;
    dfs(1,0);
    printf("%d\n",ans);
    return 0;
} 
90

bfs判断联通

技术分享
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;

int cnt,ans,flag;
int map[10][10],vis[10][10];
int mx[4]={1,0,0,-1},
    my[4]={0,-1,1,0};
string s;

struct node{
    int x,y;
}a[30];
struct T{
    int x,y;
};
queue<T>q;

bool check(){
//    cout<<"hahahha"<<endl;
    flag=false;
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=5;i++){
        for(int j=1;j<=5;j++){
            if(map[i][j]&&!vis[i][j]){
                if(flag)return false;
                flag=true;
                T a;a.x=i;a.y=j;
                q.push(a);vis[i][j]=true;
                while(!q.empty()){
                    T now=q.front();q.pop();
                    int x=now.x,y=now.y;
                    for(int k=0;k<4;k++){
                        int xx=x+mx[k],yy=y+my[k];
                        if(xx<1||yy<1||xx>5||yy>5||vis[xx][yy]||map[xx][yy]!=map[i][j])continue;
                        T tmp;tmp.x=xx;tmp.y=yy;vis[xx][yy]=true;
                        q.push(tmp); 
                    }
                } 
            }
        }
    }
    return true;
}

void debug(){
    for(int i=1;i<=5;i++){
        for(int j=1;j<=5;j++)
         printf("%d",map[i][j]);
        printf("\n");
    }
    cout<<endl<<endl;
}
void dfs(int x,int sum){
    if(x==cnt+1){
        if(check())
        ans=min(ans,sum);
        return;
    }
    map[a[x].x][a[x].y]=1;    
    dfs(x+1,sum+1);
    map[a[x].x][a[x].y]=0;
    dfs(x+1,sum);
}

int main(){
    for(int i=1;i<=5;i++){
        cin>>s;
        for(int j=1;j<=5;j++){
            map[i][j]=s[j-1]-0;
            if(!map[i][j])a[++cnt].x=i,a[cnt].y=j;
        } 
    }
    if(cnt==0){
        printf("0\n");
        return 0;
    }
    ans=5*5;
//    debug();
//    cout<<endl;
    dfs(1,0);
    printf("%d\n",ans);
    return 0;
} 
90

迭代加深搜索

技术分享
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;

int cnt,ans,flag,ret=-1;
int map[10][10],vis[10][10];
int mx[4]={1,0,0,-1},
    my[4]={0,-1,1,0};
string s;

struct node{
    int x,y;
}a[30];

inline void find(int x,int y){
    for(int i=0;i<4;i++){
        int xx=x+mx[i],yy=y+my[i];
        if(map[xx][yy]&&!vis[xx][yy]){
            vis[xx][yy]=true;
            find(xx,yy);
        }
    }
}

bool check(){
    int gg=0;
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=5;i++)
     for(int j=1;j<=5;j++)
      if(!vis[i][j]&&map[i][j]){
          gg++;if(gg>1)return false;
        vis[i][j]=true;find(i,j);
      }
    return true;
}

void dfs(int x,int sum,int deep){
    if(ret!=-1)return;
    if(sum==deep){
        if(check())ret=deep;
        return;
    }
    if(x==cnt+1)return;//md没有这个一直re 
    map[a[x].x][a[x].y]=1;    
    dfs(x+1,sum+1,deep);
    map[a[x].x][a[x].y]=0;
    dfs(x+1,sum,deep);
}

int main(){
    for(int i=1;i<=5;i++){
        cin>>s;
        for(int j=1;j<=5;j++){
            map[i][j]=s[j-1]-0;
            if(!map[i][j])a[++cnt].x=i,a[cnt].y=j;
        } 
    }
    if(cnt==0){
        printf("0\n");
        return 0;
    }
    ans=5*5;
    for(int deep=0;deep<=25;deep++){
        dfs(1,0,deep);
        if(ret!=-1){
            printf("%d\n",ret);
            return 0;
        }
    }
    return 0;
} 
AC

 

以上是关于CODEVS1049 棋盘染色的主要内容,如果未能解决你的问题,请参考以下文章

codevs——1049 棋盘染色

CODEVS——T 1049 棋盘染色

CODEVS1049 棋盘染色

[Codevs] 1014 棋盘染色

[CodeVs1050]棋盘染色2(状态压缩DP)

Codevs1922骑士共存问题(最小割,二分图最大匹配)