代码改变世界

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