和一般图上的bfs有些不同,思路上稍微有点复杂,说一下自己的理解吧。对于某种选择到达的状态如果之前已经到达过则这种选择是不应该选的,对应到一般图上如果该节点已被访问则不把该点写入队列。这点明白了,这题就没问题了。
把每个点设一个标志数组,如果该层已被访问则不写入队列,这样保证程序不会陷入死循环。
#include<stdio.h>
#include<string.h>
int s[210],quene[1000000][2],head,tail,n,a,b;
bool t[210];
void visit(int floor)
{
quene[tail][0]=floor;
quene[tail++][1]=quene[head-1][1]+1;
t[floor]=1;
}
void bfs()
{
int floor,pre,i;
quene[0][0]=a;
quene[0][1]=0;
t[a]=1;//保证不会进入死循环
while(head!=tail)
{
floor=quene[head++][0];
if(floor==b)
break;
if(floor+s[floor-1]<=n&&floor+s[floor-1]>0&&!t[floor+s[floor-1]])
visit(floor+s[floor-1]);
if(floor-s[floor-1]>0&&floor-s[floor-1]<=n&&!t[floor-s[floor-1]])
visit(floor-s[floor-1]);
}
if(floor==b)
printf("%d\n",quene[head-1][1]);
else
printf("-1\n");
}
int main()
{
while(scanf("%d",&n)&&n)
{
scanf("%d%d",&a,&b);
head=0;tail=1;
memset(quene,0,sizeof(quene));
memset(s,0,sizeof(s));
memset(t,0,sizeof(t));
for(int i=0;i<n;++i)
scanf("%d",&s[i]);
bfs();
}
return 0;
}