Dijkstra(迪杰斯特拉)算法
2010-09-24 20:13 snowkylin 阅读(549) 评论(0) 编辑 收藏 举报program dijkstra; const maxvex=100; { 图的最大顶点数 } type costtype=dword; { 权值类型为无符号整型 } graph=record cost:array[1..maxvex,1..maxvex]of costtype; { 代价矩阵 } vexnum:word; { 图的顶点数 } end; var dist:array[1..maxvex]of costtype; { 到各顶点的最短路径数值 } path:array[1..maxvex,0..maxvex]of word; { 每行记录最短路径,其中path[i,0]为到顶点i的路径长度 } i,j,v1:word; g:graph; procedure creat_graph(var g:graph); { 建立图的存储结构 } var i,j,k,edge:word; w:costtype; begin read(g.vexnum,edge); { 输入图的顶点数和边数 } { 初始化邻接矩阵 } for i:=1 to g.vexnum do for j:=1 to g.vexnum do g.cost[i,j]:=maxlongint; for i:=1 to g.vexnum do g.cost[i,i]:=0; { 主对角线为0 } for k:=1 to edge do begin read(i,j,w); { 输入起点号 边号 权值 } g.cost[i,j]:=w; g.cost[j,i]:=w; end; end; procedure shortpath(g:graph; v:word); { 顶点V到其他顶点最短路径的算法,V为顶点序号 } var i,j,k,k2:word; minqz:costtype; s:array[1..maxvex]of boolean; begin for i:=1 to maxvex do s[i]:=false; { 初始化,表示到顶点i的最短路径是否已经求得 } s[v]:=true; for i:=1 to g.vexnum do { 初始化dist数组和path数组 } begin dist[i]:=g.cost[v,i]; if (dist[i]<maxlongint) then begin path[i,1]:=i; path[i,0]:=1; end {******} else path[i,0]:=0; end; { 输出dist分量值,以显示求解过程 } for k:=1 to g.vexnum do if dist[k]<>maxlongint then write(dist[k]:5) else write('∞':5); writeln; for i:=1 to g.vexnum-1 do begin { 求顶点v的一条最短路径 } minqz:=maxlongint; j:=v; for k:=1 to g.vexnum do if (not s[k]) and ( dist[k]<minqz) then begin j:=k; minqz:=dist[k]; end; s[j]:=true; { 顶点j加入s } { 由新求得的路径修改dist数组各分量 } for k:=1 to g.vexnum do if g.cost[j,k]<>maxlongint then {本程序这条语句可省,如果costtype为longint,则不能省,否则会溢出 } if ((not s[k]) and ((dist[j]+g.cost[j,k])<dist[k])) then begin dist[k]:=dist[j]+g.cost[j,k]; for k2:=1 to path[j,0] do path[k,k2]:=path[j,k2]; path[k,k2+1]:=k; path[k,0]:=path[j,0]+1; end; for k:=1 to g.vexnum do if dist[k]<>maxlongint then write(dist[k]:5) else write('∞':5); writeln; end; end; begin assign(input,'dj.in'); reset(input); assign(output,'dj.out'); rewrite(output); creat_graph(g); read(v1); { 输入开始顶点号 } close(input); shortpath(g,v1); writeln; { 输出顶点V1到其他顶点的最短路径 } writeln('v1 to else'); writeln; for i:=1 to g.vexnum do write(dist[i]:5); writeln; for i:=1 to g.vexnum do begin writeln; write(i:5,':',v1:5); for j:=1 to path[i,0] do write(path[i,j]:5); end; close(output); end. -------------------------------------------------------------------------------- 输入样例: 7 8 1 2 6 1 4 5 1 6 8 2 3 3 3 5 4 4 3 2 4 6 4 5 7 1 1 输出: 0 6 ∞ 5 ∞ 8 ∞ 0 6 7 5 ∞ 8 ∞ 0 6 7 5 ∞ 8 ∞ 0 6 7 5 11 8 ∞ 0 6 7 5 11 8 ∞ 0 6 7 5 11 8 12 0 6 7 5 11 8 12 v1 to else 0 6 7 5 11 8 12 1: 1 1 2: 1 2 3: 1 4 3 4: 1 4 5: 1 4 3 5 6: 1 6 7: 1 4 3 5 7