博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Bellman-Ford算法

Posted on 2010-10-20 10:59  桃子在路上  阅读(711)  评论(0编辑  收藏  举报

Dijkstra算法中要求边的权非负,如果遇到负权,则可以采用Bellman-Ford算法。
【Bellman-Ford算法思想】
   
【Bellman-Ford算法实例】
 

【输入样例】
6
10
1 2 -10
1 5 19
1 6 21
2 3 5
2 4 6
2 6 11
3 4 -6
4 5 18
4 6 14
5 6 -33
1 4 
 
【输出样例】
length=-11
1->2->3->4     
                          
 

program bellman_ford;
const
  maxn=30;
var
  n,s,t:integer;
  dist:array[1..maxn] of real;
  w:array[1..maxn,1..maxn] of real;
  pre:array[1..maxn] of integer;
  vis:array[1..maxn] of boolean;
procedure init;
  var
   m,i,u,v:integer;
  begin
   assign(input,'bellford.in');
   reset(input);
   assign(output,'bellford.out');
   rewrite(output);
   readln(n,m);
   for u:=1 to n do
    for v:=1 to n do
      w[u,v]:=1e38;
   for i:=1 to m do
     readln(u,v,w[u,v]);
   readln(s,t);                    {求结点s和结点t的最短距离和路径}
  end;{init}
procedure bellford;
  var
    i,j:integer;
    change:boolean;
  begin
    for i:=1 to n do
      dist[i]:=1e38;
    dist[s]:=0;
  repeat
    change:=false;              {记录递推序列是否改变}
     for i:=1 to n do
       for j:=1 to n do
         if dist[i]+w[i,j]<dist[j]
           then begin
                  dist[j]:=dist[i]+w[i,j];
                  pre[j]:=i;
                  change:=true;
                end;
   until not change;
  end;{bellford}
procedure out(s,t:integer);
  var
    k,length,i:integer;
    path:array[1..maxn] of integer;
  begin
    if (dist[t])>1e38
      then writeln('No solutin.')
      else begin
             length:=0;
             k:=t;
             while (k<>s) do
               begin
                 inc(length);
                 path[length]:=k;
                 k:=pre[k];
               end;
               writeln('length=',dist[t]:0:0);
               write(s);
               for i:=length downto 1 do
                  write('->',path[i]);
               writeln;
             end;
end;{out}
begin
  init;
  bellford;
  out(s,t);
end.