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