广度/宽度优先搜索(BFS)

 BFS 常用于找单一的最短路线,它的特点是 “搜到就是最优解”,类似于二叉树的层序遍历算法,它的基本思想是:首先访问起始顶点v,接着由v出发,依次访问v的各个未访问过的邻接顶点w1,w2,w3,…wi,然后再依次访问w1,w2,…,wi的所有未被访问过的邻接顶点…依次类推,直到图中所有顶点都被访问过为止。类似的思想还将应用于Dijkstra单源最短路径算法和Prim最小生成树算法。其实现借助于一个辅助队列。

图示:

伪代码:

 

 1 void BFS(int x, int y){ //起点 (x, y)
 2     node n1,n2;
 3     queue<node> q;
 4 
 5     // 1.存起点
 6     n1.i=x1, n1.j=y1, n1.t=0; //存起点 n1.i=x1, n1.j=y1坐标;n1.t=0代表结构体内其他数据
 7     q.push(n1);//
 8     vis[n1.i][n1.j]=1; //标记
 9 
10     while(!q.empty()){
11         n2=q.front();//
12         q.pop();
13 
14         //2 判终点
15         if(//如 : n2.i==x2&&n2.j==y2){
16             // 输出等操作
17             return ;
18         }
19 
20         //3 可进行的操作
21         int x,y;
22         for(int i=0;i<4;i++){
23             x=n2.i+dir4[i][0];
24             y=n2.j+dir4[i][1];
25             //int dri4[4][2] = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };、
26             // n X m  
27             if(x>=0 && x<n && y>=0 && y<m && map[x][y]!="障碍" &&vis[x][y]==0){//不超边界且符合条件且没有被搜索
28                 n1.i=x;
29                 n1.j=y;
30                 n1.t=n2.t+1;
31                 vis[n1.i][n1.j]=1;
32                 q.push(n1);
33             }
34         }
35     }
36 }

 

例题:

1.细胞问题https://www.luogu.com.cn/problem/P1451

 

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 #define ll long long
 5 #define pi acos(-1)
 6 #define mod 1000000007
 7 
 8 bool vis[105][105];//标记
 9 char Map[105][105];//
10 int m, n;//行列
11 int dir[4][2]{  {-1, 0}, {1, 0}, {0, -1}, {0, 1}};//上下左右四个方向
12 ll js = 0;//细胞数目
13 typedef struct {
14     int i;
15     int j;
16 }Node;//坐标
17 
18 void bfs(int, int);
19 
20 int main() {
21     cin >> m >> n;
22     memset(vis, 0, sizeof(vis));
23     memset(Map, 0, sizeof(Map));
24     for(int i = 0; i < m; i++) {
25         scanf("%s", Map[i]);
26     }//逐行输入
27     for(int i = 0; i < m; i++) {
28         for(int j = 0; j < n; j++) {
29             if(Map[i][j] != '0' && !vis[i][j]) {//不是0且没有被访问过
30                 bfs(i, j);
31                 js++;//每搜索一次加一,每一次搜索就等于发现一个细胞
32             }
33         }
34     }
35     cout << js;
36     return 0;
37 }
38 
39 void bfs(int x, int y) {//搜索起点
40     Node former, latter;//
41     queue<Node> q;
42     former.i = x;
43     former.j = y;
44     q.push(former);//把将要对其四个方向搜索的节点存入队列
45     vis[former.i][former.j] = true;//标记
46     while(!q.empty()) {//队列不为空则说明还有不是0的点的四周没有搜索
47         int xx, yy;
48         latter = q.front();//准备对此节点进行搜索
49         q.pop();//记得删除
50         for(int i = 0; i < 4; i++) {
51             xx = latter.i + dir[i][0];
52             yy = latter.j + dir[i][1];//尝试对四个方向搜索
53             if(Map[xx][yy] != '0' && !vis[xx][yy] && xx >= 0 && xx <= m - 1 && yy >= 0 && yy <= n - 1) {//没有超出边界且不是0
54                 former.i = xx;
55                 former.j = yy;
56                 q.push(former);//把将要对其四个方向搜索的节点存入队列
57                 vis[former.i][former.j] = true;//标记
58             }
59         }
60     }
61 }
62 //for(int i = 0; i < n; i++)

 

 

BFS适合此类题目:给定初始状态跟目标状态,要求从初始状态到目标状态的最短路径。

 

参考博文:https://blog.csdn.net/Evan_love/article/details/105043595

https://blog.csdn.net/raphealguo/article/details/7523411

posted @ 2020-03-31 11:24  湖上的程序员  阅读(383)  评论(0编辑  收藏  举报