最天下午又聽了一節課,勉強把MaxiumFlow的兩個演算法寫出來了。其實兩個演算法的不同之處就在於尋找“增廣鏈”的方式——Ford-Fulkerson是隨便找一條,我就用了DFS;Edmonds-Karp要求找一條節點數最少的,我用BFS。但就是這樣的差別,兩個程式的執行效率不可同日而語——Edmonds-Karp可以過100,而Ford-Fulkerson過50時時間就不可忍受了(也許是我找增廣鏈的方式不對,因為Fish大牛的Ford-Fulkerson明顯效率比我高)。
另外,Fish大牛的兩個程式都在100+行,而我的兩個程式只在80+行(Edmonds-Karp甚至比Ford-Fulkerson少了5行),所以我懷疑我是不是少寫點東西,但就目前,我用隨機資料測試,跟Fish大牛的Edmonds-Karp結果是一樣的。我沒有看懂Fish大牛的程式,直接按照MIT課上講的東西寫的。
program ford_fulkerson;
var
g,gf:array[1..100,1..100] of longint;
path:array[0..100] of longint;
inpath:Array[1..100] of boolean;
n,f,s,t:longint;
find:boolean;
procedure findpath(s,z:longint);
var
i:longint;
begin
for i:=1 to n do begin
if (gf[s,i]>0) and (not inpath[i]) then begin
path[z]:=i;
inpath[i]:=true;
if i=t then begin
path[0]:=z;
find:=true;
inpath[i]:=false;
break;
end;
findpath(i,z+1);
inpath[i]:=false;
end;
if find then break;
end;
end;
procedure countf;
var
i:longint;
begin
f:=maxint;
for i:=1 to path[0]-1 do
if f>gf[path[i],path[i+1]] then f:=gf[path[i],path[i+1]];
end;
procedure maxflow;
var
i:longint;
begin
findpath(s,2);
repeat
countf;
for i:=1 to path[0]-1 do begin
dec(gf[path[i],path[i+1]],f);
inc(gf[path[i+1],path[i]],f);
end;
find:=false;
findpath(s,2);
until not find;
end;
procedure buildg;
var
i,j:longint;
begin
for i:=1 to n do
for j:=1 to n do begin
dec(g[i,j],gf[i,j]);
if g[i,j]<0 then g[i,j]:=0;
end;
j:=0;
for i:=1 to n do inc(j,g[i,t]);
writeln(s,'-->',t,': ',j);
end;
procedure init;
var
i,j:longint;
begin
readln(n,s,t);
while not eof do begin
readln(i,j,g[i,j]);
gf[i,j]:=g[i,j];
end;
path[1]:=s;
inpath[1]:=true;
end;
begin
init;
maxflow;
buildg;
end.
program edmonds_karp;
var
g,gf:array[1..100,1..100] of longint;
q,path,f:array[1..100] of longint;
inpath:array[1..100] of boolean;
n,s,t,z:longint;
procedure find;
var
i,j:longint;
begin
z:=1; i:=0;
while (i<z) and (not inpath[t]) do begin
inc(i);
for j:=1 to n do
if (gf[q[i],j]>0) and (not inpath[j]) then begin
inc(z);
q[z]:=j;
inpath[j]:=true;
path[j]:=q[i];
f[j]:=f[q[i]];
if f[j]>gf[q[i],j] then f[j]:=gf[q[i],j];
end;
end;
while (q[z]<>t) and (z>1) do dec(z);
fillchar(inpath,sizeof(inpath),false);
inpath[s]:=true;
end;
procedure maxflow;
var
i:longint;
begin
find;
repeat
i:=q[z];
while i<>s do begin
dec(gf[path[i],i],f[q[z]]);
inc(gf[i,path[i]],f[q[z]]);
i:=path[i];
end;
find;
until z=1;
end;
procedure buildg;
var
i,j:longint;
begin
for i:=1 to n do
for j:=1 to n do begin
dec(g[i,j],gf[i,j]);
if g[i,j]<0 then g[i,j]:=0;
end;
j:=0;
for i:=1 to n do inc(j,g[i,t]);
writeln(s,'-->',t,': ',j);
end;
procedure init;
var
i,j:longint;
begin
readln(n,s,t);
while not eof do begin
readln(i,j,g[i,j]);
gf[i,j]:=g[i,j];
end;
f[1]:=maxint;
q[1]:=s;
path[1]:=s;
inpath[1]:=true;
end;
begin
init;
maxflow;
buildg;
end.