基于染色问题(数组模拟BFS,STL-BFS,DFS)三种实现方式的模板

例题 1.洛谷 P1451 求细胞数量

题目描述

一矩形阵列由数字 0 0 0 9 9 9 组成,数字 1 1 1 9 9 9 代表细胞,细胞的定义为沿细胞数字上下左右若还是细胞数字则为同一细胞,求给定矩形阵列的细胞个数。

输入格式

第一行两个整数代表矩阵大小 n n n m m m

接下来 n n n 行,每行一个长度为 m m m 的只含字符 09 的字符串,代表这个 n × m n \times m n×m 的矩阵。

输出格式

一行一个整数代表细胞个数。

样例 #1

样例输入 #1

4 10
0234500067
1034560500
2045600671
0000000089

样例输出 #1

4

提示

数据规模与约定

对于 100 % 100\% 100% 的数据,保证 1 ≤ n , m ≤ 100 1 \le n,m \le 100 1n,m100

题目分析

对于此题,很显然我们可以先遍历所有细胞,从每一个非零的位置开始搜索(DFS,BFS都行),我在如下给出一共三种实现方式。

数组模拟队列 BFS

/*
    传统数组模拟队列 BFS
    平均内存: 686.8 kb
    平均运行时间: 3 ms
*/
struct Point
{
    int x,y;
}q[N*N];  
int head,tail;   //数组模拟队列

void bfs(int x,int y)
{
    head = tail = 0;
    a[x][y] = '0';
    q[tail].x = x;
    q[tail].y = y;
    tail++;
    
    while(tail>head)
    {
        for(int i=0;i<4;i++)
        {
            int dx = q[head].x + dir[i][0];
            int dy = q[head].y + dir[i][1];
            if(dx>=0&&dx<n&&dy>=0&&dy<m&&a[dx][dy]!='0')
            {
                a[dx][dy] = '0';
                q[tail].x = dx;
                q[tail].y = dy;
                tail++;
            }
        }
        head++;
    }
}

STL BFS

/*
    STL队列 BFS
    平均内存: 708.8 kb
    平均运行时间: 3 ms
*/
typedef pair<int,int> PII;
queue<PII> sq;  //STL队列

void stl_bfs(int x,int y)
{
    a[x][y] = '0';
    sq.push({x,y});
    
    while(sq.size())
    {
        for(int i=0;i<4;i++)
        {
            int dx = sq.front().first + dir[i][0];
            int dy = sq.front().second + dir[i][1];
            if(dx>=0&&dx<n&&dy>=0&&dy<m&&a[dx][dy]!='0')
            {
                a[dx][dy] = '0';
                sq.push({dx,dy});
            }
        }
        sq.pop();
    }
}

DFS

/*
    传统DFS
    平均内存: 637.2 kb
    平均运行时间: 3.1 ms
*/
void dfs(int x,int y)
{
    for(int i=0;i<4;i++)
    {
        int dx = x + dir[i][0];
        int dy = y + dir[i][1];
        if(dx>=0&&dx<n&&dy>=0&&dy<m&&a[dx][dy]!='0')
        {
            a[dx][dy] = '0';
            dfs(dx,dy);
        }
    }
    return;
}

总代码

#include <bits/stdc++.h>
using namespace std;

const int N = 105;
char a[N][N];
int ans,n,m;
int dir[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};

/*
    传统数组模拟队列 BFS
    平均内存: 686.8 kb
    平均运行时间: 3 ms
*/
struct Point
{
    int x,y;
}q[N*N];  
int head,tail;   //数组模拟队列

void bfs(int x,int y)
{
    head = tail = 0;
    a[x][y] = '0';
    q[tail].x = x;
    q[tail].y = y;
    tail++;
    
    while(tail>head)
    {
        for(int i=0;i<4;i++)
        {
            int dx = q[head].x + dir[i][0];
            int dy = q[head].y + dir[i][1];
            if(dx>=0&&dx<n&&dy>=0&&dy<m&&a[dx][dy]!='0')
            {
                a[dx][dy] = '0';
                q[tail].x = dx;
                q[tail].y = dy;
                tail++;
            }
        }
        head++;
    }
}

/*
    STL队列 BFS
    平均内存: 708.8 kb
    平均运行时间: 3 ms
*/
typedef pair<int,int> PII;
queue<PII> sq;  //STL队列

void stl_bfs(int x,int y)
{
    a[x][y] = '0';
    sq.push({x,y});
    
    while(sq.size())
    {
        for(int i=0;i<4;i++)
        {
            int dx = sq.front().first + dir[i][0];
            int dy = sq.front().second + dir[i][1];
            if(dx>=0&&dx<n&&dy>=0&&dy<m&&a[dx][dy]!='0')
            {
                a[dx][dy] = '0';
                sq.push({dx,dy});
            }
        }
        sq.pop();
    }
}

/*
    传统DFS
    平均内存: 637.2 kb
    平均运行时间: 3.1 ms
*/
void dfs(int x,int y)
{
    for(int i=0;i<4;i++)
    {
        int dx = x + dir[i][0];
        int dy = y + dir[i][1];
        if(dx>=0&&dx<n&&dy>=0&&dy<m&&a[dx][dy]!='0')
        {
            a[dx][dy] = '0';
            dfs(dx,dy);
        }
    }
    return;
}

int main()
{
    cin>>n>>m;
    for(int i=0;i<n;i++) cin>>a[i];
    
    /*for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            if(a[i][j]!='0') bfs(i,j),ans++;*/  //BFS
            
    /*for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            if(a[i][j]!='0') dfs(i,j),ans++;*/ //DFS
            
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            if(a[i][j]!='0') stl_bfs(i,j),ans++;  //STL BFS
    cout<<ans<<endl;
    return 0;
}

例题 2.Acwing 1097. 池塘计数

在这里插入图片描述

此题思路遇上题一致,在此不再赘述。

总代码 (DFS)

DFS写法相对与其他两种代码较短,更容易书写。

#include <bits/stdc++.h>
using namespace std;

const int N = 1010;
char a[N][N];
int n,m,ans;

void dfs(int x,int y)
{
    a[x][y] = '.';
    for(int i=-1;i<=1;i++)
        for(int j=-1;j<=1;j++)
        {
            int dx = x + i;
            int dy = y + j;
            if(dx>=0&&dx<n&&dy>=0&&dy<m&&a[dx][dy]=='W')
            {
                a[dx][dy] = '.';
                dfs(dx,dy);
            }
        }
    return;
}

int main()
{
    cin>>n>>m;
    for(int i=0;i<n;i++) cin>>a[i];
    
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            if(a[i][j]=='W') dfs(i,j),ans++;
    cout<<ans<<endl;
    return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xKazimierzx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值