看过网上的大牛说,这道题不用dijkstra其实也可以做。dijkstra只是其中一种方法,哈哈,算法真伟大。

如果你已经对dijkstra掌握的很熟悉了,那么这道题只是小菜一碟。

题目的意思是差不多电梯的思想,将其中你能到达哪一层给标记出来,权值设为1.然后其他不能到达的点都设置为无穷大,这里的无穷大也不要设置成太大,否则当你做dijkstra模板时,你就会发现出现一大堆你难以想象到的值出来。(因为设置的值过大,某些地方会溢出)。

接下来,代码吧:(代码写的不是一般的乱,调试来调试去的,但是可能这样的代码对于新手来说,更容易看懂)

#include<iostream> 
#define Max 1000001 
#define N 209 
using namespace std; 
 
int map[N][N]; 
 
int dijkstra(int s,int e,int n) 

 int i,j,min,index; 
 int visited[N],dis[N]; 
 memset(visited,0,sizeof(visited)); 
 for(i=1;i<=n;i++) 
 { 
  dis[i]=map[s][i];//这一步将起点的那个点所能到达的点的权值都标记在数组dis中,dis就是dijkstra中记录最短路的数组 
 }  
 visited[s]=1;//这是标志点是否已经走过了,就是将其拉入所谓的S集合中 
 for(i=1;i<n;i++)//下面得完全就是dijkstra思想了 
 { 
  min=Max; 
  for(j=1;j<=n;j++) 
  { 
   if(visited[j]==0&&min>dis[j]) 
   { 
    index=j; 
    min=dis[j]; 
   } 
  } 
  //cout<<min<<endl; 
  visited[index]=1
  for(j=1;j<=n;j++) 
  { 
   if(visited[j]==0&&map[index][j]+min<dis[j])//还记得上面说过的权值过大,会溢出么,就是这里 
    dis[j]=map[index][j]+min; 
  } 
 } 
  return dis[e]; 

 
int main(void

 int n,s,e,i,j; 
 int k[N],ans; 
 while(scanf("%d",&n),n) 
 { 
  scanf("%d%d",&s,&e); 
  for(i=1;i<=n;i++) 
   scanf("%d",&k[i]); 
  for(i=1;i<=n;i++) 
  { 
   for(j=1;j<=n;j++) 
    map[i][j]=Max; 
   map[i][i]=0
 
  } 
     for(j=1;j<=n;j++)//将题目转化为图论解决,这步是转换 
   { 
    if(j-k[j]>=1
     map[j][j-k[j]]=1
    if(j+k[j]<=n) 
     map[j][j+k[j]]=1
   } 
  ans=dijkstra(s,e,n); 
  if(ans==1000001
   printf("-1\n"); 
  else 
   printf("%d\n",ans); 
 } 
 return 0

如果有什么高见,或者要讨论的。QQ447814040

posted on 2011-05-10 13:09  cchun  阅读(296)  评论(0编辑  收藏  举报