Dijkstra算法
在了解 Dijkstra算法 之前,要先了解一下路径的问题
路径:
考虑带权有向图,把一条路径(仅仅考虑简单路径)上所经边的权值之和定义为该路径的路径长度或称带权路径长度。
最短路径:
从源点到终点可能不止一条路径,把路径长度最短的那条路径称为最短路径。
从一个顶点到其余各顶点的最短路径
问题描述:给定一个带权有向图G与源点v,求从v到G中其他顶点的最短路径,并限定各边上的权值大于或等于0。
单源最短路径问题:Dijkstra算法
设G=(V,E)是一个带权有向图, 把图中顶点集合V分成两组:
狄克斯特拉(Dijkstra)求解思路
Sv
U=V-Su 第1组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个
源点,以后每求得一条最短路径v,… ,u,就将u加入到集合S中,
直到全部顶点都加入到S中,算法就结束了)。
第2组为其余未求出最短路径的顶点集合(用U表示)。
Dijkstra算法过程:
(1)初始化:S只包含源点即S={v},v的最短路径为0。U包含除v外的
其他顶点,U中顶点i距离为边上的权值(若v与i有边<v,i>)或∞(若i不 是v的出边邻接点)。
(2)从U中选取一个距离v最小的顶点u,把u加入S中(该选定的
距离就是v u的最短路径长度)。
(3)以u为新考虑的中间点,修改U中各顶点j的最短路径长度:若
从源点v到顶点j(j∈U)的最短路径长度(经过顶点u)比原来最短路径长
度(不经过顶点u)短,则修改顶点j的最短路径长度。
void Dijkstra(MGraph g,int v)
{
int dist[MAXV],path[MAXV];
int s[MAXV];
int mindis,i,j,u;
for (i=0;i<g.n;i++)
{
dist[i]=g.edges[v][i]; //距离初始化
s[i]=0; //s[]置空
if (g.edges[v][i]<INF) //路径初始化
path[i]=v; //顶点v到i有边时
else
path[i]=-1; //顶点v到i没边时 }
s[v]=1; //源点v放入S中
for (i=0;i<g.n;i++) //循环n-1次
{
mindis=INF;
for (j=0;j<g.n;j++)
if (s[j]==0 && dist[j]<mindis)
{
u=j;
mindis=dist[j];
}
s[u]=1; //顶点u加入S中
for (j=0;j<g.n;j++) //修改不在s中的顶点的距离
if (s[j]==0)
if (g.edges[u][j]<INF && dist[u]+g.edges[u][j]<dist[j])
{
dist[j]=dist[u]+g.edges[u][j];
path[j]=u;
}
}
Dispath(dist,path,s,g.n,v); //输出最短路径
}