思路:
在网络中,从某个顶点Vx出发到达另外一个顶点Vi,往往有多条路径,其中,边的权值之和最小的路径称为最短路径,并称Vx为这条最短路径的源点,Vi为终点。
显然,边最少的路径不一定是最短路径。
求网络中从指定源点到其余各顶点的最短路径的问题,通常称为单源最短路径问题。
迪杰斯拉特方法:
当n个顶点的有向网络和源点都给定以后,如何求得该源点到其余各顶点的最短路径?
迪杰斯拉特提出了一个解决此问题的简单方法,即按最短路径长度由小到大的次序,逐步求得每一条最短路径。
迪杰斯拉特算法中三个辅助数组的作用:
1、d[i]记录从源点Vx到顶点Vi的“当前最短的”路径长度值
2、path[i]记录从源点Vx到顶点Vi的"当前最短的"路径上倒数第二个顶点的序号
3、s[i]=true表示从源点Vx到顶点Vi的最短路径已最终确定;s[i]=false表示源点Vx到顶点Vi的最短路径尚未最终确定。
算法key process:
初始化,确定第i条最短路径的终点,修正源点到其余各顶点的最短路径。直到全部确定完毕为止
代码:
//迪杰斯特拉算法
template <class T>
void ExtMGraph<T>::Dijkstra(int v,T* d,int* path)
{
int i,k,w;
if (v<0||v>n-1) {
cout<< “OutOfBounds”; return;
}
bool *s=new bool[n];
for (i=0;i<n;i++){
s[i]=false; d[i]=a[v][i];
if (i!=v && d[i]<INFTY) path[i]=v;
else path[i]=-1;
}
s[v]=true; //d[v]=0;
for (i=1;i<n;i++){
//确定第i条最短路径的终点序号k
k=Choose(d,s);
s[k]=true;
//修正源点到其余各顶点的最短路径
for (w=0; w<n; w++)
if (!s[w] && d[k]+a[k][w]< d[w]){
d[w]=d[k]+a[k][w];
path[w]=k;
}
}
}
template <class T>
int ExtMGraph<T>::Choose(int* d, bool* s)
{
int i,minpos; T min;
min=INFTY;
minpos=-1;
for (i=1;i<n;i++)
if (d[i]<min &&!s[i]){
min=d[i];
minpos=i;
}
return minpos;
}
算法分析:
-上述算法的执行时间为O(n^2);
-如果只希望求从源点到某一特定顶点之间的最短路径,也需要与求单源最短路径相同的时间复杂度O(n^2)