迪杰斯特拉算法主要是,在图中找两个点(源点到其他顶点)之间的最短路径。一步一步的求出两点之间的最短路径,过程中是基于上一次已经求出的最短路径的基础上,来去求得更远顶点的最短路径,最终得到你要的结果。
//代码来源《大话数据结构》,有增删。
/* Dijkstra算法,求有向网G的v0顶点到其余顶点v的最短路径P[v]及带权长度D[v] */
/* P[v]的值为前驱顶点下标,D[v]表示v0到v的最短路径长度和 */
#define MAXVEX 20
#define INFINITY 65535
void Dijkstra(MGraph G, int v0, Patharc *P, ShortPathTable *D)
{
int v,w,k,min;
int final[MAXVEX]; /* final[w]=1表示求得顶点v0至vw的最短路径 */
for(v=0; v<G.numVertexes; v++) /* 初始化数据 */
{
final[v] = 0; /* 全部顶点初始化为未知最短路径状态 */
(*D)[v] = G.arc[v0][v]; /* 将与v0点有连线的顶点加上权值 */
(*P)[v] = 0; /* 初始化路径数组P为0 */
}
(*D)[v0] = 0; /* v0至v0路径为0 */
final[v0] = 1; /* v0至v0不需要求路径 */
/* 开始主循环,每次求得v0到某个v顶点的最短路径 */
for(v=1; v<G.numVertexes; v++)
{
min=INFINITY; /* 当前所知离v0顶点的最近距离 */
for(w=0; w<G.numVertexes; w++) /* 寻找离源点最近的顶点 */
{
if(!final[w] && (*D)[w]<min)
{
k=w;
min = (*D)[w];
}
}
final[k] = 1; /* 将目前找到的最近的顶点置为1 */
/* 修正当前最短路径及距离 */
for(w=0; w<G.numVertexes; w++)
{
/* 如果经过v顶点的路径比现在这条路径的长度短的话 */
if(!final[w] && (min+G.arc[k][w]<(*D)[w])) //这里为什么用k作为比较的下一个行。因为,上个for循环。找到了本节点与下一个点的最短路径的连接点就是k ,再去找与k这一行有最短路径的点(k与其他顶点。)。
{ /* 说明找到了更短的路径, 修改当前路径长度 */
(*D)[w] = min + G.arc[k][w]; /* min是上一个顶点到本顶点的最短距离,加上本节点到与本节点有边且没有访问过的点(即w点)的最小距离,组成源点到w的最短距离,存放再D数组里面 */
(*P)[w]=k;
}
}
}
}
用最短路径去解决。
Hdoj --1548
思路:转化为两点之间是否可达,再转化为用迪杰斯特拉算法求最短路径就行了。
#include<stdio.h>
#include<string.h>
#define inf 0x3fffffff
int map[205][205];
int dijks(int s,int t,int n)
{
bool visit[205];
int dis[205];
int i,j,k,min;
memset(visit,false,sizeof(visit));
visit[s]=true;
for(i=1;i<=n;++i)
dis[i]=map[s][i];
for(i=1;i<n;++i)
{
min=inf;
k=1;
for(j=1;j<=n;++j)
{
if(!visit[j]&&min>dis[j])
{
min=dis[j];
k=j;
}
}
if(k==t||min==inf)
break;
visit[k]=true;
for(j=1;j<=n;++j)
{
if(!visit[j]&&dis[k]+map[k][j]<dis[j])
dis[j]=dis[k]+map[k][j];
}
}
if(dis[t]==inf)
return -1;
else
return dis[t];
}
int main()
{
int n,a,b,i,j;
int button[205];
while(scanf("%d",&n),n)
{
scanf("%d%d",&a,&b);
for(i=1;i<=n;++i)
scanf("%d",&button[i]);
if(a==b)
{
printf("0\n");
continue;
}
if(a>n||b>n)
{
printf("-1\n");
continue;
}
for(i=1;i<=n;++i)
for(j=1;j<i;++j)
map[i][j]=map[j][i]=inf;
for(i=1;i<=n;++i) //初始化图,只要想到这一步,问题基本就解决了。
{
if(i+button[i]<=n)
map[i][i+button[i]]=1;
if(i-button[i]>0)
map[i][i-button[i]]=1;
}
printf("%d\n",dijks(a,b,n));
}
return 0;
}