一、BFS的介绍
BFS(广度优先搜索,也可称宽度优先搜索)是连通图的一种遍历策略。因为它的基本思想是从一个顶点V0开始,辐射状地优先遍历其周围较广的区域。
广度优先搜索(BFS)类似于二叉树的层序遍历算法,它的基本思想是:首先访问起始顶点v,然后由v出发,依次访问v的各个未被访问过的邻接顶点w1,w2,w3….wn,然后再依次访问w1,w2,…,wi的所有未被访问过的邻接顶点,再从这些访问过的顶点出发,再访问它们所有未被访问过的邻接顶点….以此类推,直到途中所有的顶点都被访问过为止。类似的想法还将应用与Dijkstra单源最短路径算法和Prim最小生成树算法。
广度优先搜索是一种分层的查找过程,每向前走一步可能访问一批顶点,不像深度优先搜索(DFS)那样有回退的情况,因此它不是一个递归的算法,为了实现逐层的访问,算法必须借助一个辅助队列并且以非递归的形式来实现。

二、BFS搜索的步骤
    1、首先创建一个visit[ ]数组和一个队列q,分别用来判断该位置是否已经访问过及让未访问过的点入队;
    2、初始化visit[ ]数组,清空q队列;
    3、让起点start入队,并使该点的visit置1;
    4、while(!q.empty()){......}执行搜索操作,
        a、取出队头元素后使队头元素出队,判断该元素是否为目标到达点;
        b、如果是目标点,就返回结果(一般是最短时间、最短路径);
        c、如果不是目标点,就继续访问与其相邻的位置点,将可走的相邻的位置点入队,并更新visit[ ]数组;

三、BFS的应用
BFS算法一般应用于单源最短路径的搜索。

1、寻找非加权图(或者所有边权重相同)中任两点的最短路径。

2、寻找其中一个连通分支中的所有节点。(扩散性)3、bfs染色法判断是否为二分图。

四、核心代码

#include<iostream>
#include<queue>
#include<string.h>
#define maxn 105
using namespace std;int n,m;    //矩阵的大小
int sx,sy;
int vis[maxn][maxn],s[maxn][maxn],t[maxn][maxn];
queue<struct node>Q;
int px[]={1,-1,0,0};        //人可走的4个方向
int py[]={0,0,1,-1};
struct node{int x,y,step;
}r,p,q;int BFS()
{   //清空队列及初始化vis数组 while(!Q.empty())Q.pop();memset(vis,0,sizeof(vis));p.x=sx;p.y=sy;p.step=0;vis[p.x][p.y]=1;Q.push(p);while(!Q.empty()){p=Q.front();Q.pop();if(s[p.x][p.y]=='t')return p.step;for(int i=0;i<4;i++){q=p;q.x+=px[i];q.y+=py[i];q.step++;if(q.x<0||q.y<0||q.x>=n||q.y>=m)continue;//访问未被访问过的位置,且此时是在火势蔓延到此前访问的,再将该位置入队if(vis[q.x][q.y]==0&&q.step<t[q.x][q.y]){vis[q.x][q.y]=1;Q.push(q);}}}return -1;
}int main(){//功能需求代码 //........return 0;
}

五、例题

【奇怪的电梯】

-题目描述-

有一天我做了一个梦,梦见了一种很奇怪的电梯。大楼的每一层楼都可以停电梯,而且第i层楼(1<=i<=N)上有一个数字Ki(0<=Ki<=N)。电梯只有四个按钮:开,关,上,下。上下的层数等于当前楼层上的那个数字。当然,如果不能满足要求,相应的按钮就会失灵。例如:3 3 1 2 5代表了Ki(K1=3,K2=3,……),从一楼开始。在一楼,按“上”可以到4楼,按“下”是不起作用的,因为没有-2楼。那么,从A楼到B楼至少要按几次按钮呢?点击打开链接

-输入格式-

共二行。第一行为 3 个用空格隔开的正整数,表示 N,A,B(1≤N≤200, 1≤A,B≤N)N,A,B(1≤N≤200,1≤A,B≤N) 。第二行为 N 个用空格隔开的非负整数,表示 K_i。

-输出格式-

一行,即最少按键次数,若无法到达,则输出 -1−1 。

-样例数据-

input

5 1 5
3 3 1 2 5
output

3
-分析-

这道题所要求的是最小值(最少要按的按钮数)。用BFS找到答案便可以退出(DFS不能保证答案为最优解)。要注意边界:是否可以继续往上或向下(没有0楼,-1楼......)。

-代码-

#include<bits/stdc++.h>
using namespace std;
int n,a,b;
int que[222]={};
int k[222]={};
int vis[222]={};//标记是否询问过
int tmp[222]={};
int head=1,tail=0;//队首队尾指针
void bfs(int now)
{for(;head<=tail;)//当队列不为空时{int top=que[head];//top为队首的层数head++;//弹出队首if(top==b)return ;//假如已经到达了目标(b)层,直接退出if(top+k[top]<=n&&vis[top+k[top]]==0)//假如没有超出边界并且没有访问过{que[++tail]=top+k[top];//入队tmp[top+k[top]]=tmp[top]+1;//次数为上一次+1vis[top+k[top]]=1;//标记}if(top-k[top]>=1&&vis[top-k[top]]==0){que[++tail]=top-k[top];tmp[top-k[top]]=tmp[top]+1;vis[top-k[top]]=1;}}return ;
}
int main()
{cin>>n>>a>>b;for(int i=1;i<=n;i++)cin>>k[i];que[++tail]=a;vis[a]=1;bfs(a);if(vis[b]==0)//假如没有访问过cout<<-1<<endl;else//访问过cout<<tmp[b]<<endl;return 0;
}

【青铜莲花池】

-题目描述-

为了让奶牛们娱乐和锻炼,农夫约翰建造了一个美丽的池塘。这个长方形的池子被分成了 M 行 N 列个方格(1 ≤ M, N ≤ 30) 。一些格子是坚固得令人惊讶的莲花,还有一些格子是岩石,其余的只是美丽、纯净、湛蓝的水。贝西正在练习芭蕾舞,她站在一朵莲花上,想跳到另一朵莲花上去,她只能从一朵莲花跳到另一朵莲花上,既不能跳到水里,也不能跳到岩石上。贝西的舞步很像象棋中的马步:每次总是先横向移动 M1 (1 ≤ M1 ≤ 30)格,再纵向移动 M2 (1 ≤ M2 ≤ 30, M1≠M2)格,或先纵向移动 M1 格,再横向移动 M2 格。最多时,贝西会有八个移动方向可供选择。给定池塘的布局和贝西的跳跃长度,请计算贝西从起点出发,到达目的地的最小步数,我们保证输入数据中的目的地一定是可达的。点击打开链接

-输入格式-

第一行:四个用空格分开的整数:M,N,M1 和 M2第二行到 M + 1 行:第 i + 1 行有 N 个用空格分开的整数,描述了池塘第i 行的状态:0 为水,1 为莲花,2 为岩石,3 为贝西所在的起点,4 为贝西想去的终点。

-输出格式-

一行,从起点到终点的最少步数。

-样例数据-

input

4 5 1 2
1 0 1 0 1
3 0 2 0 4
0 1 2 0 0
output

2
-分析-

贝西的跳跃方式像马(马按“日”字形走(点击打开链接))。只要列出八个方向,判断这几个方向是否可以进行跳跃(跳跃到的位置必须有莲叶且先前没有进行过标记),如果可以则入队,不断弹出队首,直至队列为空或者跳到目标位置,跳出循环。

-代码-

#include<bits/stdc++.h>
using namespace std;
int m,n,m1,m2;
int a[33][33]={};
int vis[33][33]={};
int ans[33][33]={};
int lx,ly;
struct kk
{int x;int y;
} que[3333]={};
int head=1,tail=0;
int bfs()
{for(;head<=tail;){int x=que[head].x;int y=que[head].y;//记录队首的坐标head++;//弹出队首if(x==lx&&y==ly)return ans[x][y];//返回答案if(x+m1<=m&&y+m2<=n&&vis[x+m1][y+m2]==0&&a[x+m1][y+m2]==1){que[++tail]=(kk){x+m1,y+m2};vis[x+m1][y+m2]=1;ans[x+m1][y+m2]=ans[x][y]+1;}if(x-m1>0&&y-m2>0&&vis[x-m1][y-m2]==0&&a[x-m1][y-m2]==1){que[++tail]=(kk){x-m1,y-m2};vis[x-m1][y-m2]=1;ans[x-m1][y-m2]=ans[x][y]+1;}if(x-m1>0&&y+m2<=n&&vis[x-m1][y+m2]==0&&a[x-m1][y+m2]==1){que[++tail]=(kk){x-m1,y+m2};vis[x-m1][y+m2]=1;ans[x-m1][y+m2]=ans[x][y]+1;}if(x+m1<=m&&y-m2>0&&vis[x+m1][y-m2]==0&&a[x+m1][y-m2]==1){que[++tail]=(kk){x+m1,y-m2};vis[x+m1][y-m2]=1;ans[x+m1][y-m2]=ans[x][y]+1;}if(x+m2<=m&&y+m1<=n&&vis[x+m2][y+m1]==0&&a[x+m2][y+m1]==1){que[++tail]=(kk){x+m2,y+m1};vis[x+m2][y+m1]=1;ans[x+m2][y+m1]=ans[x][y]+1;}if(x-m2>0&&y-m1>0&&vis[x-m2][y-m1]==0&&a[x-m2][y-m1]==1){que[++tail]=(kk){x-m2,y-m1};vis[x-m2][y-m1]=1;ans[x-m2][y-m1]=ans[x][y]+1;}if(x-m2>0&&y+m1<=n&&vis[x-m2][y+m1]==0&&a[x-m2][y+m1]==1){que[++tail]=(kk){x-m2,y+m1};vis[x-m2][y+m1]=1;ans[x-m2][y+m1]=ans[x][y]+1;}if(x+m2<=m&&y-m1>0&&vis[x+m2][y-m1]==0&&a[x+m2][y-m1]==1){que[++tail]=(kk){x+m2,y-m1};vis[x+m2][y-m1]=1;ans[x+m2][y-m1]=ans[x][y]+1;}}//八个方向进行跳跃
}
int main()
{cin>>m>>n>>m1>>m2;for(int i=1;i<=m;i++)for(int j=1;j<=n;j++){cin>>a[i][j];if(a[i][j]==3){que[++tail]=(kk){i,j};vis[i][j]=1;}//如果为初始位置,入队,并进行标记if(a[i][j]==4){lx=i;ly=j;a[i][j]=1;//为了方便,这样只需要判断a[i][j]为1时可以跳跃} //记录结束位置} cout<<bfs()<<endl;//bfsreturn 0;
}

BFS(广度优先搜索算法)相关推荐

  1. bfs广度优先搜索算法_图的广度优先搜索(BFS)

    bfs广度优先搜索算法 What you will learn? 您将学到什么? How to implement Breath first search of a graph? 如何实现图的呼吸优先 ...

  2. DFS深度优先搜索算法/BFS广度优先搜索算法(c/c++)

    深度优先搜索算法(DFS) 深度优先搜索算法思路:(有点贪心算法的意思) 1,从某个给定结点a出发,访问它 2,查找关于a的邻接点,查找到a的第一个邻接点b之后,对b结点进行DFS搜索,也就是对b结点 ...

  3. BFS广度优先搜索算法//宽度优先搜索算法

    BFS宽度优先搜索算法,又称广度优先搜索,是最简便的图的搜索算法之一,这一算法也是很多重要的图的算法的原型. Dijkstra单源最短路径算法和Prim最小生成树算法都采用了和宽度优先搜索类似的思想. ...

  4. 图的深度(DFS)/广度优先搜索算法(BFS)/Dijkstra

    类比二叉树先序遍历与图深度优先搜索 在引入图的深度优先搜索之前,为了更加容易理解.先考究一种特殊的图---二叉树的深度优先搜索算法---即二叉树的递归遍历方法. 二叉树的前序遍历算法: void Tr ...

  5. 深度优先搜索算法(Depth-First-Search,DFS)与广度优先搜索算法(Breadth-First Search,BFS)理解

    最近学习到了这两种经典的算法,谈一下自己的理解 深度优先搜索算法(Depth-First-Search,DFS) 这个算法会尽可能深的搜索树的分支.当节点v的所在边都己被探寻过,搜索将回溯到发现节点v ...

  6. 【BFS三维路径规划】基于matlab广度优先搜索算法无人机三维路径规划【含Matlab源码 270期】

    一.获取代码方式 获取代码方式1: 通过订阅紫极神光博客付费专栏,凭支付凭证,私信博主,可获得此代码. 获取代码方式2: 完整代码已上传我的资源:[三维路径规划]基于matlab广度优先搜索算法无人机 ...

  7. 广度优先搜索算法(BFS)详解

    参考:https://www.cnblogs.com/tianqizhi/p/9914539.html 广度优先搜索算法(又称宽度优先搜索)是最简便的图的搜索算法之一,这一算法也是很多重要的图的算法的 ...

  8. 广度优先搜索算法(有向图和无向图)

    广度优先搜索算法的思想:以v作为源点出发访问其他节点,首先使用队列存储节点,再从队列中取出节点,遍历查找v和其他连通的节点,将和v连通的节点并且未被访问过的节点入队,遍历完和v连通的节点:再从队列中取 ...

  9. 步步为营(十六)搜索(二)BFS 广度优先搜索

    上一篇讲了DFS,那么与之相应的就是BFS.也就是 宽度优先遍历,又称广度优先搜索算法. 首先,让我们回顾一下什么是"深度": 更学术点的说法,能够看做"单位距离下,离起 ...

最新文章

  1. 【C++】【六】约瑟夫问题
  2. JavaScript中的异步梳理(0)
  3. C/C++ 一段代码区分数组指针|指针数组|函数指针|函数指针数组
  4. java取二进制其中两位_Java:二进制(原码、反码、补码)与位运算(示例代码)...
  5. 宁德时代预计一季度净利润超9.9亿元 同比增长超140%
  6. 虚拟机可以识别usb无线网卡,但一直提示设备正在运行中--解决方法
  7. 深度学习之RNN、LSTM及正向反向传播原理
  8. 序列化和反序列化(八)——Externalizable接口
  9. 你不能强迫别人进步,跟别人没法强迫你进步一样
  10. python密码字典库_python生成密码字典的方法
  11. EMC-电磁兼容-电磁骚扰的耦合机理
  12. 《社会心理学》第一章读书笔记
  13. feedsky 话题 营销
  14. 带你了解“不拘一格去创新,别出心裁入场景”的锐捷
  15. 2019-行远自迩,登高自卑
  16. Pixel: Multi-signatures for Consensus
  17. 计算机休眠拖动鼠标不起作用,电脑待机后按鼠标无法唤醒怎么办
  18. 基带信号与频带信号的基础认识
  19. ZT 王国维先生“人生三大境界”的具体含义是什么?
  20. 经纬度与UTM(Universal Transverse Mercator Projector:通用横轴卡墨托投影)的坐标变换代码

热门文章

  1. 驱动依赖_「世经研究」焦炭行业--仍旧依赖政策驱动
  2. python怎么查看列表_Python 小白,关于对于列表的+=操作不明白,查了半天也不知道怎么查,并且查询无果,请人指点?...
  3. 中科院开源协会镜像站 Android SDK镜像测试发布
  4. 深圳职业技术学院计算机工程学院江学锋,毕业论文附属材料07013505刘丽.doc
  5. linux键盘输入重复,关于修改键盘输入
  6. 无法上网dns转发_苹果笔记本上网很慢怎么回事?macbook无线上网慢的解决方法...
  7. android-ultra-pull-to-refresh list,[Android]Ultra-Pull-To-Refresh之listview下拉刷新、上拉加载的用例...
  8. Java多线程-生产者与消费者
  9. 二、分布式文件系统HDFS及其简单使用
  10. 十九、深入Python匿名函数