您的位置:首页 > 其它

贪心算法——单源最短路径 dijkstra

2012-12-24 20:20 260 查看
关于单源最短路径的问题非常典型,这里没有给出分析与证明,仅仅给出了实现。

需要指出的是,许多实现仅给出了最短路径的长度,而没有给出“最短路径”,这里用给出了实现。

如程序中那样,定义一个数组p
,其中p[i]代表“起始点v到顶点i的最短路径中,除i本身的最后一个顶点”,即着这条路径上i的前驱顶点,这个顶点随着“更多顶点的最短路径被求出”这个过程而变化。

当求出v到所有顶点的最短路径以后,同时也求出了最终的p
。于是可以按下列回溯的方法来求出每条最短路径序列:

对于顶点j,在其最短路径上其前驱pre=p[j],i=<pre<n且pre!=j,说明“到顶点j的最短路径”是基于“到顶点pre的最短路径”的,这样一直回溯,直到pre=v(单源点),这些pre值就构成了最短路径序列。

#include<iostream>
usingnamespacestd;
#defineN5
#defineMAX65535
intg

;
voidmin_path(intv,long*d,int*p)
{
inti=0;
intj=0;
bools
={false};
for(i=0;i<N;i++)
for(j=0;j<N;j++)
if(g[i][j]==-1)
g[i][j]=65536;
for(i=0;i<N;i++)
{
d[i]=g[v][i];
if(d[i]==MAX)
p[i]=0;
else
p[i]=v;
}

s[v]=true;
d[v]=0;
p[v]=0;

intk=0;
for(i=0;i<N;i++)
{
intmin=65535;
for(j=0;j<N;j++)
{
if(j!=v&&s[j]==false)
{
if(d[j]<=min)
{
min=d[j];
k=j;//k是V集合中具有最短“特殊路径的顶点”,所谓特殊路径即是从顶点v到k只经过U中的顶点。
}
}
}
s[k]=true;//将k从V集合中并入到U集合中
for(j=0;j<N;j++)
{
if(s[j]==false&&d[j]>d[k]+g[k][j])
{
d[j]=d[k]+g[k][j];//更新其他在V中的顶点的最短距离。
p[j]=k;
}
}
}
}
intmain()
{
longd
;
intp
;//p[i]代表到达顶点i的最短路径的前驱节点,随着路径变化而变化
inti=0;
for(i=0;i<N;i++)
{
for(intj=0;j<N;j++)
cin>>g[i][j];
}
min_path(0,d,p);
for(i=0;i<N;i++)
cout<<d[i]<<"";
cout<<endl;
//输出每条最短路径
for(i=0;i<N;i++)
{
//if(i!=0)
{
intpre=p[i];
while(pre!=0)
{
cout<<pre<<"";
pre=p[pre];
}
cout<<endl;
}
}
}



转自:http://blog.csdn.net/clearriver/article/details/4229012
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法