//关于BFS
1、把起始点放入queue;
2、重复下述2步骤,直到queue为空为止:
1) 从queue中取出队列头的点;
2) 找出与此点邻接的且尚未遍历的点,进行标记,然后全部放入queue中。
宽度优先搜索算法伪代码:void bfs()
Node bfs(node source,node target){
memset(visit,0,sizeof(visit));
queue<node>Q;
Q.push(source);
visit[source] = 1;//找到初始状态
while(!Q.empty()){
Node a=Q.front();
Q.pop();
if(a == target){ return a; }
for(对于a所有的后继节点b){
if(visit[b]) continue;
Q.push(b);
visit[b] = 1;//剪枝,保证节点之进入队列一次
}
}
}
可以看出宽度优先搜索法可以求出步数最少的解,即深度最少的解.
//经典例题:奇怪的电梯:https://www.luogu.com.cn/problem/P1135
题解:https://www.luogu.com.cn/problem/solution/P1135
https://cloud.tencent.com/developer/article/1094364
https://blog.csdn.net/janesilver/article/details/82218455
#include <iostream>
#include <queue>
using namespace std;
typedef struct {
int floor; //当前所处的楼层编号
int pushcount; //到达该楼层所经历的步数(按按钮次数)
} QElement;
queue<QElement> q; //定义元素类型为QElement的队列q
int n,a,b;
int s[1000]; //数组s记录每个楼层按按钮后能上下的楼层数
int t[1000]={0}; //数组t记录各个楼层是否已经到达过(已访问过)
int main()
{
QElement e1,e2;
int i;
cin >> n >> a >> b;
for (i=1; i<=n; i++) cin >> s[i];
e1.floor=a;
e1.pushcount=0;
q.push(e1); //初始状态入队:当前楼层为a,按按钮次数为0
t[a]=1; //记录当前楼层已访问过
while (!q.empty()) //当队列不为空时,继续宽度优先搜索
{
e2=q.front(); //获取队头元素
q.pop(); //队头元素出队(注意:c++的队列模板类中,获取队头元素并不会将该元素从队列中删除,需要使用pop函数删除该元素)
if (e2.floor==b) break; //检查当前状态的楼层编号是否为b,是则说明已经找到最终解,跳出循环
i=e2.floor+s[e2.floor]; //按向上按钮后能够到达的楼层
if (i<=n && t[i]==0) //如果按向上按钮能到达的楼层有效并且未访问过该楼层
{
e1.floor=i;
e1.pushcount=e2.pushcount+1;
q.push(e1);
t[i]=1; //设该楼层为已访问过
}
i=e2.floor-s[e2.floor]; //按向下按钮后能够到达的楼层
if (i>=1 && t[i]==0) //如果按向下按钮能到达的楼层有效并且未访问过该楼层
{
e1.floor=i;
e1.pushcount=e2.pushcount+1;
q.push(e1);
t[i]=1; //设该楼层为已访问过
}
}
//如果当前楼层为b,输出按按钮次数,否则无解(输出-1)
if (e2.floor==b) cout << e2.pushcount;
else cout << -1;
}
#include <bits/stdc++.h>
using namespace std;
int n,s,t;
int a[210];
int vis[210];
struct pos{//状态表示
int level;//此时的位置
int steps;//此时走的步数
};
void bfs(){
pos cur,nex;
cur.level=s;
cur.steps=0;
queue<pos> q;
q.push(cur);
vis[s]=1;
while(!q.empty()){
cur=q.front();
q.pop();
if(cur.level==t){
printf("%d\n",cur.steps);
return;
}
nex.level=cur.level + a[cur.level];
nex.steps=cur.steps + 1;
if(nex.level<=n && vis[nex.level] ==0) {
vis[nex.level] = 1;
q.push(nex);
}
nex.level=cur.level - a[cur.level];
nex.steps=cur.steps + 1;
if(nex.level>=1 && vis[nex.level] ==0) {
vis[nex.level] = 1;
q.push(nex);
}
}
printf("-1\n");
}
int main(){
while(scanf("%d",&n)!=EOF){
if(n == 0) break;
scanf("%d%d",&s,&t);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
vis[i]=0;//初始化
}
bfs();
}
return 0;
}