Dijkstra
1) 适用条件&范围:
a) 单源最短路径(从源点s到其它所有顶点v);
b) 有向图&无向图(无向图可以看作(u,v),(v,u)同属于边集E的有向图)
c) 所有边权非负(任取(i,j)∈E都有Wij≥0);
2) 算法描述:
a) 初始化:dis[v]=maxint(v∈V,v≠s); dis[s]=0; pre[s]=s; S={s};
b) For i:=1 to n
1.取V-S中的一顶点u使得dis[u]=min{dis[v]|v∈V-S}
2.S=S+{u}
3.For V-S中每个顶点v do Relax(u,v,Wu,v)
c) 算法结束:dis[i]为s到i的最短距离;pre[i]为i的前驱节点
3) 算法优化:
使用二叉堆(Binary Heap)来实现每步的DeleteMin(ExtractMin,即算法步骤b中第1步)操作,算法复杂度从O(V^2)降到O((V+E)㏒V)。推荐对稀疏图使用。
使用Fibonacci Heap(或其他Decrease操作O(1),DeleteMin操作O(logn)的数据结构)可以将复杂度降到O(E+V㏒V);如果边权值均为不大于C的正整数,则使用Radix Heap可以达到O(E+V㏒C)。但因为它们编程复杂度太高,不推荐在信息学竞赛中使用。
注:程序使用二叉堆
程序:
program mtx_grp;
const num=10; max=10000;
type
grp=array[1..num,1..num] of integer;
rcd=set of 1..num;
arr=array[1..num] of integer;
arr2=array[1..num] of rcd;
var
i,j,w,m,n,e,k:integer;
g:grp;
visited:array[1..num] of boolean;
path:arr2;
dist,s:arr;
procedure createmtx;
var i,j,k:integer;
begin
for i:=1 to n do
for j:=1 to n do
g[i,j]:=max;
for k:=1 to e do
begin
readln(i,j,w);
g[i,j]:=w;
g[j,i]:=w;