ACM菜鸟的学习笔记(1)--BFS篇

注意:本博客是一名真正的菜鸟写的,目的在于记录学习过程,以及给想要学习新算法的同学一些经验,代码写的丑了或者讲的不对了希望大家不要介意~

初识BFS

最近在某大牛的熏陶下,学习了BFS,虽说BFS作为最基础的搜索算法,学起来并不费劲,但我现在还不敢说我已经完全掌握。如果有写的不对的地方,欢迎各位大佬指正。

BFS是什么

BFS全称宽度优先搜索算法(又称广度优先搜索),是最简便的图的搜索算法之一,这一算法也是很多重要的图的算法的原型。Dijkstra单源最短路径算法和Prim最小生成树算法都采用了和宽度优先搜索类似的思想。BFS属于一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。换句话说,它并不考虑结果的可能位置,彻底地搜索整张图,直到找到结果为止。(取自百度百科)

而按我自己的理解,BFS和DFS1这对双胞胎,是最基础的搜索算法,也是最简单最粗暴最好理解的图的搜索算法,在所有图论算法中,BFS多用于求迷宫的最短路径,比较经典的模板题我会列在下面。

那么BFS的基本思路是什么呢?按照我的理解,是通过确定的某一个点,往外展开地毯式的搜索,通过储存可能存在的路径、步数、格子总数等来得最短路径、迷宫、踩格子等题目类型的解。是最基础的图算法。那么接下来上模板题。

初步理解

那么我来讲讲我学习BFS后对BFS的理解,以及讲解。(如果有讲的不好的地方请大家指出来)

这里有一张图↓

这就是一张5*5的非常经典的BFS类型迷宫图,我会用这张图讲解BFS的基本原理。

我们先找到@的位置(可以理解为起始点或是根节点)。然后从@的位置往外(上下左右)扩散,然后进行一系列的判断,将需要继续扩散的点储存,并储存步数,进入下一次循环,再从存储的点往外(上下左右)扩散,再进行一轮储存。已经踩过的点就不需要储存了,这样就可以保证你踩到这个点所经过的路径一定是最短的。而缺点就在于由于要铺开整张图,在时间复杂度上有劣势

这里讲解的只是最基础的一种BFS,而还有不少变异的BFS,比如下面蓝桥杯比赛的卡片换位,使用BFS写就需要一定的思维能力。

模板题

1.HDU–1312 Red and Black(红与黑)
2.HDU–2612 Find a way(找到目的地)

1.Red and Black(红与黑)

戳这里去看题

这道题实际上用DFS会更优,但作为模板题来练手还是可以的。

这道题的大意是你在一个房间当中,房间的地板只有红和黑两种颜色,’.‘是红色的地板,’#‘是黑色的地板,’@'是你自己。你很喜欢红色,所以你只能走到红色的地板上,不能走到你不喜欢的黑色地板上(虽然我不知道为什么踩个地板就好像能要了你的命XD),并且你的腿比较短,一次只能走到相邻的地板上,不能斜着走。那么问题来了,你能踩到的地板有多少块?

这道题就是非常标准的图的搜索题,以下是我的AC代码:

#include "cstdio"
#include "cstring"
#include "queue"
using namespace std;
const int MAXN = 21;
bool use[MAXN][MAXN];			//判断这个点是否被'踩'过 
char Map[MAXN][MAXN];			//存图 
queue<int> q;					//储存待扩展的点 
int n,m,ans;
void BFS(){
   
	while(!q.empty()){
   
		int a=q.front();									//取出队列最前端的点
		q.pop();
		int b=q.front();
		q.pop();
		ans++;
		if(a>0) if(Map[a-1][b]=='.'&&!use[a-1][b]){
   			//依次判断是否越界,是否为'.',是否被踩过
			q.push(a-1);									//将这个点存入队列
			q.push(b);
			use[a-1][b]=true;								//这个点被踩过
		}
		if(b>0) if(Map[a][b-1]=='.'&&!use[a][b-1]){
   
			q.push(a);
			q.push(b-1);
			use[a][b-1]=true;
		} 
		if(a<m-1) if(Map[a+1][b]=='.'&&!use[a+1][b]){
   
			q.push(a+1);
			q.push(b);
			use[a+1][b]=true;
		} 
		if(b<n-1) if(Map
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值