我们生而属于天空,|

KukCair

园龄:1年粉丝:0关注:1

二维 bfs 基础笔记

一、寻找连通块

1. 基本思路

找到一个未被走过的点,以这个点为起点,将与此点相连的所有点标记为走过,答案数 +1

2. 代码实现

#include <bits/stdc++.h>
using namespace std;
struct p{
    int x, y;
};
queue<p> q;
int n, m, cnt;//最终答案为cnt
int dx[] = {1, -1, 0, 0}, dy[] = {0, 0, 1, -1};//方向数组
char mp[1005][1005];//原矩阵
bool f[1005][1005];//标记数组
void bfs(){
    while(!q.empty()){
        int mx = q.front().x, my = q.front().y;
        q.pop();
        for(int i = 0; i <= 3; i++){
            int nx = mx + dx[i], ny = my + dy[i];
            if(nx < 1 || ny < 1 || nx > n || ny > m) continue;
            if(mp[nx][ny] =='0') continue;
            mp[nx][ny] = '0';//标记此点走过
            q.push({nx, ny});
        }
    }
}
int main(){
    cin >> n >> m;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            cin >> mp[i][j];
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= m; j++){
            if(mp[i][j] != '0'){//未被标记过
                cnt++;//答案数+1
                q.push({i, j});//以此点为起点
                bfs();
            }
        }
    }
    cout << cnt;
    return 0;
}

例题:

P1451 求细胞数量

P6757 [BalticOI2013] Tracks in the Snow 雪中足迹


二、经典 bfs 最短路问题

1. 基本思路

以某一格为起点,每步可以向上、下、左、右四个方向走一格,输出到达终点的最少步数。

2. 代码实现

#include <bits/stdc++.h>
using namespace std;
struct p{
    int x, y;
};
int n, m, sx, sy, ex, ey, step[1005][1005];
bool mp[1005][1005], f[1005][1005];
int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1};
// step[i][j]:到达(i,j)的步数
// f[i][j]:(i,j)是否走过
// dx[]/dy[]:方向数组
void bfs(){
    queue<p> q;
    q.push({sx, sy});
    while(!q.empty()){
        int mx = q.front().x, my = q.front().y;
        q.pop();
        if(mx == ex && my == ey){// 到终点
            cout << step[mx][my];
            return;
        }
        for(int i = 0; i <= 3; i++){
            int nx = mx + dx[i], ny = my + dy[i];
            if(nx > n || nx < 1 || ny > m || ny < 1) continue;// 越界的
            if(f[nx][ny] || mp[nx][ny]) continue;//走过的/不能走的
            f[nx][ny] = 1;// 标记
            step[nx][ny] = step[mx][my] + 1;// 步数
            q.push({nx, ny});
        }
    }
}
int main(){
    cin >> n;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)
            cin >> mp[i][j];
    cin >> sx >> sy >> ex >> ey;
    bfs();
    return 0;
}

例题:

P1746 离开中山路

B3625 迷宫寻路


3.01bfs

AT_abc176_d [ABC176D] Wizard in Maze

经典的 01bfs 问题。是的你没看错就是之前总结的题(

移步 我的文章


4. 变形(?)

P1141 01迷宫

P1443 马的遍历

P1332 血色先锋队

posted @   KukCair  阅读(13)  评论(2编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起