Dijkstra算法使用了广度优先搜索解决非负权有向图的单源最短路径问题,算法最终得到一个最短路径树。
Dijkstra算法的时间复杂度依赖于最小优先队列的具体实现,若使用数组,时间复杂度为O(V^2+E),V是顶点个数,E是边数,若使用最小堆,时间复杂度为O((V+E)lgV),若使用裴波那契堆,时间复杂度是O(VlgV+E)。
下面是一个使用数组的普通实现。
#include <iostream.h>
#include <limits.h>
#define N 5
int Graph[N][N] = {
{0,3,INT_MAX,8,INT_MAX},
{3,0,5,INT_MAX,4},
{INT_MAX,5,0,4,7},
{8,INT_MAX,4,0,2},
{INT_MAX,4,7,2,0}
};
int Len[N] = {0,INT_MAX,INT_MAX,INT_MAX,INT_MAX};
int Pre[N];
void main()
{
int count=0,si=0;
int in[N] = {0};
while(count<N)
{
int tempmin;
tempmin=INT_MAX;
for(int i=0;i<N;i++)
{
if(in[i]==0&&Len[i]<tempmin)
{
tempmin=Len[i];
si=i;
}
}
in[si]=1;
count++;
for(i=1;i<N;i++)
{
if(in[i]==0&&tempmin<INT_MAX&&Graph[si][i]<INT_MAX&&(tempmin+Graph[si][i])<Len[i]) //不加tempmin<INT_MAX&&Graph[si][i]<INT_MAX条件,可能会造成tempmin+Graph[si][i]溢出
{
Len[i]=tempmin+Graph[si][i];
Pre[i] = si;
}
}
}
for(int i=0;i<N;i++)
{
int path[N] = {0};
if(Len[i]<INT_MAX)
{
int temp=i;
path[N-1] = i;
int j = N-2;
while(Pre[temp]!=0)
{
path[j] = Pre[temp];
temp = Pre[temp];
j--;
}
cout<<i<<":"<<Len[i]<<" "<<"0";
for(int k=0;k<N;k++)
if(path[k]!=0)
cout<<"->"<<path[k];
cout<<endl;
}
else
{
cout<<i<<":Unreachable!"<<endl;
}
}
}