看过网上的大牛说,这道题不用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