• 广度/宽度优先搜索(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

  • 相关阅读:
    C++11之function模板和bind函数适配器
    C++11之右值引用(三):使用C++11编写string类以及“异常安全”的=运算符
    C++11之右值引用(二):右值引用与移动语义
    C++11之右值引用(一):从左值右值到右值引用
    C++Singleton的DCLP(双重锁)实现以及性能测评
    信息熵
    ip访问网站和localhost访问网站中top使用
    方差与协方差
    js获取file控件的完整路径(上传图片预览)
    对线性回归,logistic回归和一般回归
  • 原文地址:https://www.cnblogs.com/knightoflake/p/12603916.html
Copyright © 2020-2023  润新知