BFS常见模板题(初学BFS推荐,附例题由浅入深)

BFS类题目:主要考查对广度搜索的理解。

BFS相比于暴力枚举来说效率更高。
BFS只要将范围矩阵扫一次即可得出答案。
本文通过队列来实现求解,当然也可以用其他方式实现广度搜索。

First question:馋嘴羊

题目
BFS思路(可能会比较抽象,建议结合代码理解):
第一步:输入矩阵、开始吃草位置
第二步:判断开始吃草位置1有没有草
如果有草
第三步:将该位置1入队
第四步:取队伍首元素为位置x
第五步:判断位置x上、下、左、右的位置有没有草
第六步:将有草的位置入队
第七步:将位置x对应的inf置为true,ans++
重复四~七步直到队伍中没有成员
最后输出ans
如果没草
输出0

#include<bits/stdc++.h>
#include<queue>
using namespace std;
int n, m, x, y, ans=0;
const int maxn=1000;
int matrix[maxn][maxn];
bool inf[maxn][maxn]={
   false};

int X[4]={
   0, 0, -1, 1};
int Y[4]={
   -1, 1, 0, 0};

struct node{
   
	int x;
	int y;
}Node, top;

bool judge(int xx, int yy)
{
   
	if(xx<0||yy<0||xx>=n||yy>=m)
	return false;
	if(inf[xx][yy]==true||matrix[xx][yy]==0)
	return false;
	return true;
}


void BFS(int x, int y)
{
   
	queue<node> q;
	Node.x=x;
	Node.y=y;
	q.push(Node);
	while(!q.empty())
	{
   
		top=q.front();
		int nx=top.x;
		int ny=top.y;
		for(int i=0; i<4; i++)
		{
   
			if(judge(nx+X[i], ny+Y[i]))
			{
   
				Node.x=nx+X[i];
				Node.y=ny+Y[i];
				q.push(Node);
			}
		}
		ans++;
		inf[nx][ny]=true;
		q.pop();
	}
}


int main()
{
   
	cin>>n>>m>>x>>y;
	
	for(int i=0; i<n; i++)
	for(int j=0; j<m; j++)
	cin>>matrix[i][j];
	
	if(matrix[x][y]==1)
		BFS(x, y);
	cout<<ans;
	
	return 0;
}
Second question:走出迷宫

给定一个nm大小的迷宫,其中 * 代表不可通过的墙壁,而"."代表平地,S代表起点,T代表终点。移动过程中,如果当前位置是(x,y)(下标从0开始),且每次只能前往上下左右(x,y+1),(x,y-1),(x-1,y)(x+1,y)四个位置的平地,求从起点S达到终点T的最少步数。

Sample Input:
5 5 //5行5列
… //迷宫信息
...
.S.
.**T

2 2 3 4 //起点S的坐标和终点T的坐标

Sample Output:
7
上面样例中,S的坐标为(2,2) T的坐标为(4,3)
注意:这道题与前面又略有不同,题目要求最少步数。
我们可以通过改变结点node结构,加入setp变量,作为记录每个位置的最少步数,这也体现了结构的灵活性。

#include<bits/stdc++.h>
#include<queue>
using namespace std;

struct node{
   
	int x;
	int y;
	int step;
}Node, top;

const int maxn=1000;
char matrix[maxn][maxn];
bool inf[maxn][maxn]={
   false};
int X[4]={
   0,0,-1,1};
int Y[4]={
   -1,1,0,0};
int n, m, ant;
node a, S, T;

bool judge(int xx, int yy)
{
   
	if(xx
  • 9
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值