【广度优先搜索BFS】

2025博客之星年度评选已开启 10w+人浏览 1.3k人参与

【BFS】

推荐视频链接
推荐好文

核心思想:层层递进,先广后深

运用手段:队列

简述:(推荐好文中有详述)

简单的说,就像石子落入水中溅起涟漪,一环一环,不断向周围扫过去。而“一环一环”就是通过队列实现的。首先将起点入队,之后取得他的坐标后便将他出队,然后根据这个坐标对其周围的点一 一扫过去,也就是一 一将他们入队,同时标记,之后都是只取队首的元素,取完后就出队,循环下去;

例题:

1.遍历
在这里插入图片描述
思路:
在边上的0一定不是围起来
所以只要找边上的就0,再涟漪过去

代码:

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

int n;
vector <vector<int>> g(50,vector <int> (50)),s(50,vector <int> (50,0));//g表地图,s表判断数组 
struct node//想将一个坐标压入队列中,需要借助结构体或者二元数组 
{
	int x,y;
};
queue <node> qu;//队列 
int dx[]={1,-1,0,0};//方向数组 
int dy[]={0,0,-1,1};

void bfs(int x,int y)
{
	s[x][y]=1;//将起点标记 
	qu.push((node) {x,y});//让起点进队 
	while(qu.size())//如果队列非空 
	{
		int ax=qu.front().x,ay=qu.front().y;//取队首元素 
		qu.pop();//用完了就扔 
		for(int i=0;i<4;i++)//方向 
		{
			int sx=ax+dx[i],sy=ay+dy[i];
			if(sx>=1&&sx<=n&&sy>=1&&sy<=n&&!s[sx][sy])//不能出地图,不能是标记过的 
			{
				s[sx][sy]=1;//标记 
				qu.push((node){sx,sy});//再让这个坐标入队 
			}
		}
	}
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			cin>>g[i][j];
		}
	}
	s=g;//让判断数组先与地图相等 
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n;j++)
			{
				if(i==1 || j==1 || i==n || j==n)//如果是在边上的0的话就一个不是围起来的0 
				{
					if(g[i][j]==0 && !s[i][j])//不能是判断过的 
					{
						bfs(i,j);
						
					}
				}
			}
		}
	
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(s[i][j]==1 && g[i][j]==1) cout<<1<<" ";//仔细想想 
			else if(s[i][j]==1 && !g[i][j]) cout<<0<<" ";
			else if(!s[i][j] && !g[i][j])cout<<2<<" ";
		}
		cout<<endl;
		
	}
	
	return 0;
}

2.最短距离
在这里插入图片描述
代码:

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

//bfs用的不是递归,而是循环 

char g[1005][1005];//地图 
int s[1005][1005];//不在是判断数组,而是从起点走到每个位置的最短路程 
struct node//依旧 
{
	int x,y;
};
int dx[]={1,0,0,-1};//依旧 
int dy[]={0,1,-1,0};
int n;
queue <node> qe; 
int x1,yz,x2,y2;

void bfs(int x,int y)
{
	g[x][y]='1';
	qe.push((node){x,y});
	while(qe.size())
	{
		int ax=qe.front().x,ay=qe.front().y;
		qe.pop();
	    for(int i=0;i<4;i++)
	    {
		    int sx=ax+dx[i],sy=ay+dy[i];
		    if(sx>=1&&sx<=n&&sy>=1&&sy<=n&&g[sx][sy]=='0')
		    {
		    	g[sx][sy]='1';
			    s[sx][sy]=s[ax][ay]+1;//重点在这,每格=上一格+1步 
			    qe.push((node){sx,sy});
			    if(sx==x2 && sy==y2) return;//如果找到了就退出就行了 
		    }
	    }
	}
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			cin>>g[i][j];
		}
	}
	
	cin>>x1>>yz>>x2>>y2;
	bfs(x1,yz);
	cout<<s[x2][y2];
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值