BFS(广度优先搜索)

一.简介

bfs是一种图搜索算法,用于在图或树等数据结构中遍历或搜索节点。属于一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。

二.作用

常用来搜索最短路径。

三.bfs搜索步骤

1.创建一个存储图(示例坐标)a[][]。

b[][]用来标记位置(标记过的位置不在遍历)。

int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
存储向四个方向遍历的运算坐标(0,1),(1,0),(0,-1),(-1,0);

typedef pair<int,int> pll;(可以存储一组坐标,也可用结构体)

queue<pll>q;(这里需要一个队列,利用队列先进先出的特性)。

q.push({x1,y1});   b[x1][y1]=0;//标记起始位置;

while(!q.empty())//判断容器是否为空;

在循环中执行pll p=q.front();用p<int ,int>存储q中的第一对数;

q.pop();//存储后,出队。

对p<int ,int>中的坐标进行四个方向遍历(红色区域跳过,即a[4][2],a[4][4]=false)

if(a[x][y]=false)contiue;  if(b[x][y]>0)continue;标记过的跳过。

 

1,12345

2

x-1,y不变
3x不变y-1起点b[3][3]=0x不变y+1
4————x+1,y不变b[4][3]=b[3][3]+1————
5b[5][3]=b[4][3]+1

终点③

b[5][4]=b[5][3]+1

将遍历的方向坐标入栈,并用b[][]标记坐标.例b[x][y]=1;

if(x==x2&&y==y2)cout<<b[x][y]<<endl;判断是否找到终点坐标,

找到,输出停止循环。否则继续循环,以其中一个点(x+1,y不变即(4,3))为例,对坐标进行四个方向遍历(4,4)跳过,(5,3)入栈,用b[5][3]=b[5][4]++标记(4,2)跳过,(3,3)跳过。

继续循环,对(5,3)方向遍历,(5,4)入栈,b[5][4]=b[5][3]+1;if(x==x2&&y==y2)cout<<b[x][y]<<endl;找到终点坐标,

四.题码展示

题目描述

爱与愁大神买完东西后,打算坐车离开中山路。现在爱与愁大神在 x1​,y1​ 处,车站在 x2​,y2​ 处。现在给出一个 n×n(n≤1000) 的地图,0 表示马路,1 表示店铺(不能从店铺穿过),爱与愁大神只能垂直或水平着在马路上行进。爱与愁大神为了节省时间,他要求最短到达目的地距离(每两个相邻坐标间距离为 1)。你能帮他解决吗?

输入格式

第 1 行包含一个数 n。

第 2 行到第 n+1 行:整个地图描述(0 表示马路,1 表示店铺,注意两个数之间没有空格)。

第 n+2 行:四个数 x1​,y1​,x2​,y2​。

输出格式

只有 11 行,即最短到达目的地距离。

输入输出样例

输入                 输出

3                4
001                       
101
100
1 1 3 3

代码展示:

#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;
void bfs(int ,int);
int x1,y1,x2,y2,n,x,y;
char a[1010][1010];
int b[1010][1010];
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};

typedef pair<int,int> pll;
queue<pll>q;
int main()
{
	memset(b,-1,sizeof b);
	cin>>n;
	for(int i=1;i<=n;i++)
		scanf("%s",a[i]+1);//+1指向第二行第二列。 
		scanf("%d%d%d%d",&x1,&y1,&x2,&y2);	
	bfs(x1,y1);	
	return 0;
}
void bfs(int x1,int y1)
{		
		q.push({x1,y1});
		b[x1][y1]=0;//标记起始位置; 
		while(!q.empty())//判断容器是否为空; 
		{
			pll p=q.front();用p<int ,int>存储q中的第一对数; 
			q.pop();//存储后,出队。 
			for(int i=0;i<4;i++)//对存储的坐标进行操作 
			{
				x=p.first+dx[i];//四个方向进行遍历; 
				y=p.second+dy[i];
				if(b[x][y]>=0)continue;//标记过则跳过 
				if(a[x][y]=='1')continue;//测试数据(避开点) 
				if(x<1||x>n||y<1||y>n)continue;//出界跳过 
				b[x][y]=b[p.first][p.second]+1;//次数累加 
				q.push({x,y});//将得到的新坐标入队。 
				if(x==x2&&y==y2)cout<<b[x][y]<<endl;
			}
		}
}

  • 26
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值