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.