Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Алгоритмы на графах / shortest / bf
.pas{ TODO: Ґ а Ў®в Ґв }
{ graphs by boris }
{ «Ј®аЁв¬ ЃҐ««¬Ґ -”®а¤ }
const
maxn = 100; { ¬ ЄбЁ¬ «м®Ґ Є®«-ў® ўҐаиЁ }
oo = maxint div 2; { ЎҐбЄ®Ґз®бвм }
var
a: array [1..maxn, 1..maxn] of integer; { ¬ ваЁж ᬥ¦®бвЁ }
d: array [1..maxn] of longint; { Єа вз ©иЁҐ ЇгвЁ }
p: array [1..maxn] of integer; { ¤ҐаҐў® Єа вз ©иЁе Їг⥩ (SPT) }
v: array [1..maxn] of boolean; { ЁбЇ®«м§®ў «Ё ўҐаиЁ }
n: longint; { Є®«-ў® ўҐаиЁ }
{ init: ЁЁжЁ «Ё§ жЁп Ё з⥨Ґ ¤ ле }
procedure init;
var
i, j, x, y, nn, z: longint;
begin
for i := 1 to maxn do { Ја д ЎҐ§ ॡҐа }
for j := 1 to maxn do
a[i, j] := oo;
fillchar(d, sizeof(d), 0);
fillchar(p, sizeof(p), 0);
fillchar(v, sizeof(v), false); { ўҐаиЁл Ґ ЁбЇ®«м§®ў л }
{ з⥨Ґ ¤ ле }
{ assign(input, 'dijkstra.in');}
assign(input, 'negcycle.in');
reset(input);
read(n);
read(nn);
for i := 1 to nn do
begin
read(x, y, z);
a[x, y] := z;
{ a[y, x] := z;} { Ґб«Ё Ґ®аЁҐвЁа®ў л© Ја д }
end;
end;
{ print: ЇҐз вм ¬ ваЁжл ¬Ґ¦®бвЁ }
procedure print;
var
i, j: integer;
begin
writeln;
writeln('Љ®«ЁзҐбвў® ўҐаиЁ: ', n);
writeln('Њ ваЁж ᬥ¦®бвЁ');
for i := 1 to n do
begin
for j := 1 to n do
if a[i, j] = oo then
write('oo':3)
else
write(a[i, j]:3);
writeln;
end;
end;
{
Function (!) to find shortest pathes from one vertex to all other,
without asumpation, that all edge weights are nonnegative. This
function implements Bellman-Ford algo. The return value is FALSE when
there exists cycle with negative weight. TRUE otherwise.
Time complexity is O(V*E) ~ O(V^3) for full graph.
}
function bellman_ford(s: integer): boolean;
var
i, j, k: integer;
begin
for i := 1 to N do
begin
p[i] := -1;
d[i] := maxlongint;
end;
p[s] := 0;
d[s] := 0;
for i := 1 to n do { жЁЄ« Ї® ўбҐ¬ ўҐаиЁ ¬ Єа®¬Ґ Ёбв®Є }
begin
for j := 1 to n do { ¤«п ўбҐе ўҐаиЁ }
if (d[j] > d[i]+a[i, j]) then { зҐаҐ§ m ¬®¦® ¤®©вЁ ¤® j Ўлбв॥ }
begin
d[j] := d[i] + a[i, j]; { 㬥ми Ґ¬ а ббв®пЁҐ ®в Ёбв®Є }
p[j] := i; { Ё§¬ҐпҐ¬ ЇаҐ¤Є j }
end;
end;
for i := 1 to n do
begin
for j := 1 to n do
begin
if (a[i, j] <> oo) and
(d[i] > d[j] + a[j, i]) then
begin
bellman_ford := false;
exit;
end;
end;
end;
bellman_ford := true;
end;
{write_path: ЇЁиҐв Єа вз ©иЁ© Їгвм Ё§ s ў x }
procedure write_path(s, x: integer);
begin
if x <> s then
write_path(s, p[x]);
write(x, ' ');
end;
begin
init;
writeln;
writeln('Ља вз ©иЁҐ ЇгвЁ Ё§ ®¤®Ј® Ёбв®Є ў бҐвпе б Ґ®ваЁж ⥫мл¬Ё ўҐб ¬Ё ॡҐа');
writeln('Ђ«Ј®аЁв¬ „Ґ©Єбвал');
if not bellman_ford(1) then
write('Ќ ©¤Ґ ®ваЁж ⥫мл© жЁЄ«')
else
write('ЌҐ ©¤Ґ ®ваЁж ⥫мл© жЁЄ«');
print;
write('Ља вз ©иЁ© Їгвм Ё§ 1-®© ўҐаиЁл ў 4-го ўҐаиЁг: ');
write_path(1, 4);
end.