题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1548
#include <iostream>
#include <string.h>
#include <stdio.h>
#define MAX 0x3f3f3f3f
using namespace std;
/***************************************************************************************************************
题意:题意:电梯每层有一个不同的数字,例如第n层有个数字k,那么这一层只能上k层或下k层,
但是不能低于一层或高于n层,给定起点与终点,要求出最少要按几次键
思路;
1,每层电梯看做点,每个电梯是否可以到达用单向边表示,即 Map[i][j] = 1
2,采用dijkstra求最短路即可
***************************************************************************************************************/
int Map[205][205];
int dist[205],visit[205];
int dijkstra(int st,int n)
{
memset(dist,MAX,sizeof(dist));
memset(visit,0,sizeof(visit));
for(int i = 1;i <= n;i ++)
dist[i]=Map[st][i];
dist[st]=0;
visit[st]=1;
for(int i = 1;i < n;i ++){
int id,ans=MAX;
for(int j = 1;j <= n;j ++){
if(!visit[j] && dist[j] < ans){
ans=dist[j];
id=j;
}
}
visit[id]=1;
for(int j = 1;j <= n;j ++)
if(!visit[j] && dist[id]+Map[id][j] < dist[j])
dist[j]=dist[id]+Map[id][j]; //啊,不能忍!转移方程写错!wa了快一个小时!
}
}
int main()
{
int n,st,ed;
while(cin>>n)
{
if(n == 0) break;
cin>>st>>ed;
memset(Map,MAX,sizeof(Map));
int temp;
for(int i = 1;i <= n;i ++){
cin>>temp;
if(temp == 0) continue;
if(temp+i <= n) //该层可到上界
Map[i][temp+i]=1; //单边
if(i-temp > 0) //该层可到下界
Map[i][i-temp]=1;
}
dijkstra(st,n);
if(st == ed)
cout<<"0"<<endl;
else if(dist[ed] != MAX)
cout<<dist[ed]<<endl;
else
cout<<"-1"<<endl;
}
return 0;
}