我们发现,如果我们把同一层的点存起来,那么,先进先出的话,同层点在被访问过后,才会接着访问下一层的点。而先进先出正是队列的特点,所以,我们可以使用队列来实现BFS。
2.例题分析
https://vjudge.net/problem/HDU-1548
奇怪的电梯,可以使用BFS来解决,当然也可以使用DFS和Dijkstra
来解决(有兴趣可以尝试下)
奇怪的电梯题目输入是当前所在楼层,目的楼层,楼层总数,每层电梯只能上下的层数。
输出是最少的次数,不能到达则-1。
#include <queue>
#include <iostream>
#include <cstring>
using namespace std;
queue <int> q;
int num,s,e;
int a[1000];
int step[1000];
void bfs(){
int m,n;
while(!q.empty())
{
m = q.front();//取出当前队列第一个数,即当前楼层
q.pop();
n = m + a[m];//往上移动到的楼层数
if(n >= 1 && n <= num && step[n] == -1)
{
step[n] = step[m] + 1;//步数自增
q.push(n);//把当前(移动后的)楼层数加入队列
}
n = m - a[m];//往下移动到的楼层数
if(n >= 1 && n <= num && step[n] == -1)
{
step[n] = step[m] + 1;//步数自增
q.push(n);//把当前(移动后的)楼层数加入队列
}
}
//队列为空,则表示没有可以移动的位置了,即所有能走的楼层均走过
cout << step[e] << endl;
}
int main(){
while(scanf("%d",&num)!= EOF)
{
if(num == 0)
{
break;
}
scanf("%d%d",&s,&e);//开始结束楼层
for(int i = 1 ; i <= num ; i++)
{
scanf("%d",&a[i]);//每层固定上下移动的层数
}
memset(step,-1,sizeof(step));
step[s] = 0;
q.push(s);//将开始层数加入队列
bfs();
}
return 0;
}
BFS对于求无权路的最短路径很方便,遍历一遍,到了对应的节点,则可以说是最短路径,对于有权图可以采用Dijkstra等等。
三.总结
BFS和DFS主要是一种遍历图的方式,理解透彻具体是什么,该怎么遍历,熟练之后便可以很快上手,那么该怎么熟练呢?当然是理解+刷题(笑。再来推荐道题目Serial Time! ,DFS,BFS都可以尝试下(逃