
开学了,每天上课耽误不少时间…好想带着电脑去上课呀qwq.
个人认为广度优先搜索要比深度优先搜索难一些,难在需要借助很多数据结构来解决问题
核心思想
个人认为广度优先搜索的核心思想是队列
在一切开始之前,首先要学会队列的用法:
数据结构的特性就不说了
1 |
|
广度优先搜索的模板
1 |
void (起始点) { |
只看模板会让人看得一头雾水,其简单来说就是:
- 每次将当前访问的结点从队列中拿出来
- 检查他所能直接到达的结点并将它们入队
- 此结点出队
- 再从队列中取出首部结点循环操作,直到队伍中不再含有任何结点,此时广度搜索结束
每次将当前访问结点的直接后继结点入队,体现了广度优先搜索的过程
最简单的广度优先搜索:再探走迷宫
1 |
5 6 |
第一行输入为地图的大小,之后是地图的样式。
要求输出到达终点的最小步数,如果无法到达终点,输出-1
因为是广度优先搜索,所以第一次达到终点时的步数就是最小步数
对于每个结点,定义一个结构体struct
1 |
//x,y为该结点的下标,d为搜索到此结点时的步数 |
另外为了防止重复访问(避免在两块地板之间来回走),与深度优先搜索一样,需要定义一个bool型数组存储是否访问过这块地板
1 |
bool vis[110][110]; |
下面给出源码,程序的各部分功能已在代码中给出注释
1 |
|
简单例题
一维坐标

只是比走迷宫抽象了一点点,这里的每个节点分为三个方向,分别访问并将能访问到的结点入队即可
1 |
|
密码锁

1 |
|
与其他数据结构结合的广度优先搜索
一维跳棋


这道题难度明显提升,(其实仔细想想还好,就是需要在结构体中用到其他的数据结构来存储一些必要信息)
每个结点用来存储当前的棋盘结构和空格位置
每次在队首拿到新结点时,通过空格的位置来进一步确定下一次移动棋子所能达到的样式
因为最后输出的是整个移动棋子过程中所有的空格位置,所以在结构体中需要定义一个vector数组来存储每次的空格位置,因此,bfs函数的返回类型应该为 vector
另外为了防止重复访问,定义一个映射map:用来记录每一种棋盘情况是否能被访问过。
1 |
map<string, bool> vis |
(棋盘结构用string存储)
用swap函数交换棋子和空格的位置,每个结点对应棋子都有四种跳跃方式,分别是两侧与空格不相邻的棋子向空格跳跃,和两侧与空格相邻的棋子向空格移动
很重要的一点:每个结点在每个方向交换棋子和空格位置后,都需要将已交换的妻子和空格复原成此结点最初的样式,便于此结点对应棋子其他形式的改变
1 |
|
三阶平面魔方


用整型数存储魔方样式
同样用一个映射map存储当前魔方样式是否被访问过
1 |
map<int, bool> vis;//当前魔方样式,是否被访问 |
因为魔方转动时我是用二维数组,代码写起来非常麻烦(..•˘_˘•..)
与其他题目一样,在每个结点中每次交换魔方方块之后不要忘记还原(还原的代码swap应该与旋转魔方方块的代码swap是对称的,而不应相同)
比如下面的swap代码,应该是对称的(我最开始就错在还原的swap顺序写错了,导致没有真正还原)
1 |
//right |
下面给出源码
1 |
|
吃糖的时间


同样是麻烦的代码,用二位vector存储每个小朋友与其他小朋友的关系
1 |
vector<int> child[100005]; |
但是用二维vector存储关系其实有一个严重的问题,比如说关系中某一行的输入为 6 5
1 |
int a, b; |
这里如果我单纯用二维vector存储关系,只能通过6号小朋友找到5号小朋友,而不能通过5号小朋友找到6好小朋友(最开始我在这里卡了很长时间)
因此在二维vector录入数据时,不仅要child[a].push_back(b); 还需要 child[b].push_back(a);,将两个人的关系在每个人的vector中都体现出来
因为用了bool型数组保存对应小朋友有没有被访问,所以无需考虑重复的问题
下面给出源码
1 |
|
难度提高:蒜头回家


此题难度进一步提升,需要先拿到钥匙再到达终点
我定义了两个队列,在第一个队列中拿到钥匙,此时将此钥匙结点入队列2,并在队列2中继续广度优先搜索,因为拿到钥匙后可以走拿到钥匙之前已经走过的地板,所以需要新开一个bool型数组,存储拿到钥匙后访问的路径
这里我最开始是在队列2每次访问到终点后将队列2清空,同时将新开的vis2数组值全部改为false,这种方法会超时。
为了节约时间做出以下修改:
- 在队列2中的遍历,只要步长已经超过此时已经得到过的最小步长,直接清空队列退出
- 定义一个bool型三维数组用来存储拿到钥匙后的访问路径,省去每次重新为vis2数组赋值的时间
其余部分详情看注释,下面给出源码
1 |
|
难度再次提升
题太难,时间有限考前先不整理了




近期评论