BFS概念
广度优先搜索,还可称为宽度优先搜索,简称BFS,是一种图算法,用于遍历或搜索图或树的数据结构。它从图的起始节点开始,逐层访问与起始节点相邻的节点,然后逐层扩展,直到找到目标节点或遍历完整个图。在BFS过程中,每一层的节点都会在同一层级上被访问,因此它遍历的是图的广度。
BFS可用于解决下列问题
个人认为:
- 从A点出发是否存在到达B的路径;
- 从A出发到达B的最短路径:
百度查的:
-
最短路径问题: BFS可以用来寻找两个节点之间的最短路径,因为它会优先访问与起始节点相邻的节点,逐层扩展,直到找到目标节点。
-
连通性问题: BFS可以检测图中的连通性,即判断两个节点是否相互可达。
-
拓扑排序: 如果图是一个有向无环图(DAG),BFS可以用于拓扑排序,确定节点之间的依赖关系顺序。
-
迷宫求解: BFS可以用于解决迷宫问题,通过逐层扩展,找到从起始位置到目标位置的路径。
-
网络广播: 在计算机网络中,BFS可以用于广播消息或查找网络中的特定节点。
BFS算法的过程:
-
选择起始节点: 从图或树的某个节点开始,将其标记为已访问并加入队列。
-
遍历相邻节点: 从队列中取出一个节点,访问其所有未被访问过的相邻节点,将它们标记为已访问并加入队列。这确保了按照广度的顺序逐层遍历。
-
重复步骤2: 重复以上步骤,直到队列为空。这意味着已经遍历完整个图或树,或者找到了目标节点。
-
检查目标节点: 如果目标节点在遍历过程中被找到,算法结束。否则,算法会继续执行,直到队列为空。
BFS使用队列的数据结构来实现。在遍历过程中,节点按照它们被发现的顺序加入队列,并按照队列的先进先出(FIFO)原则进行处理。这确保了每一层的节点都在同一层级上被访问。
需要注意的是,BFS会保证找到的路径是最短路径,因为它按照层级逐步扩展,优先考虑与起始节点相邻的节点。这使得BFS在解决最短路径问题时非常有效。w
为什么需要用对列?
网上找的
例题:
P1746 离开中山路 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题目描述
爱与愁大神买完东西后,打算坐车离开中山路。现在爱与愁大神在 x1,y1 处,车站在 x2,y2 处。现在给出一个 n×n(n≤1000) 的地图,0 表示马路,1 表示店铺(不能从店铺穿过),爱与愁大神只能垂直或水平着在马路上行进。爱与愁大神为了节省时间,他要求最短到达目的地距离(每两个相邻坐标间距离为 1)。你能帮他解决吗?
输入格式
第 1 行包含一个数 n。
第 2 行到第 n+1 行:整个地图描述(0 表示马路,1 表示店铺,注意两个数之间没有空格)。
第 n+2 行:四个数 x1,y1,x2,y2。
输出格式
只有 1 行,即最短到达目的地距离。
输入输出样例
输入
3 001 101 100 1 1 3 3输出
4
#include<iostream> //如果记不住这么多的头文件,可以用万能头文件<bits/stdc++.h>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
#define x first //宏定义first,second为 x,y 使代码变得稍微有条理(个人认为)
#define y second
#define M 1010
typedef pair<int,int> PII; //存坐标
queue<PII> q; //定义对列
int n,sx,sy,fx,fy;
int dist[M][M]; //记录起点到某一点的距离,同时也表示从起点到该点需要移动(搜索)几次
char g[M][M]; //形成地图
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1}; //四个方向
int bfs(int x1,int y1){
memset(dist,-1,sizeof(dist)); //全部初始化为 -1
q.push({x1,y1}); //入队
dist[x1][y1]=0; //起点标记为 0
while(q.size()){ //队列不空,还可以用 !q.empty()表示
auto t=q.front(); //取出对头
q.pop(); //弹出对头
for(int i=0;i<4;i++){
int a=t.x+dx[i];
int b=t.y+dy[i];
if(a<1||a>n||b<0||b>n)continue; //不能超出边界
if(g[a][b]!='0')continue; //不是 0(0为马路),则不能行走
if(dist[a][b]>=0)continue; //初始值为 -1,如果此处没有走过,则需要大于等于 0
q.push({a,b}); //符合要求的点,入队
dist[a][b]=dist[t.x][t.y]+1; //用前一个位置到起点的距离 +1,算出该点到起点的距离
if(dist[fx][fy]>0) //表示已经到了终点,返回起点到终点移动(搜索)的次数,即dist【x2】【y2】
return dist[fx][fy];
}
}
return -1;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",g[i]+1);
}
scanf("%d%d%d%d",&sx,&sy,&fx,&fy);
int res=bfs(sx,sy);
printf("%d\n",res);
return 0;
}