?? max_flow.pas
字號:
const
maxn=30;
type
nodetype=record
l{標號標志,為前繼節點,>0為相前路,<0為相后路},p{檢查標志,1已檢查,0未檢查}:integer;
end;
arctype=record
c{最大可行流},b{最小可行流},f{實際流}:integer;
end;
gtype=array[0..maxn,0..maxn] of arctype;{圖}
ltype=array[0..maxn] of nodetype;{可改進路}
var
lt:ltype;
g:gtype;
n,s,t:integer;
f:text;
procedure readg;
var
str:string;
i,m,j:integer;
begin
write('file=');
readln(str);
assign(f,str);
reset(f);
readln(f,n);
fillchar(g,sizeof(g),0);
fillchar(lt,sizeof(lt),0);
for i:=1 to n do
begin
for j:=1 to n do read(f,g[i,j].c);
readln(f);
end;
close(f);
end;{讀入}
function check:integer;
var
i:integer;
begin
i:=s;
while (i<=t) and not((lt[i].l<>0) and (lt[i].p=0)) do inc(i);{找已標號而未檢查的點}
if i>t then check:=0 else check:=i;
end;
function ford(var a:integer):boolean;
var
i,j,m,x:integer;
begin
ford:=true;
fillchar(lt,sizeof(lt),0);
lt[s].l:=s;
repeat{找可擴展路}
i:=check{找可擴展節點};
if i=0 then exit{若不可改進則退出};
for j:=s to t do
if (lt[j].l=0{若j已被檢查}) and ((g[i,j].c<>0) or (g[j,i].c<>0)) then
begin
if (g[i,j].f<g[i,j].c) then lt[j].l:=i;
if (g[j,i].f>0) then lt[j].l:=-i;{引一條從j到i的相前或相后路}
end;
lt[i].p:=1;{令i已被檢查}
until (lt[t].l<>0);{直到匯點被標號}
m:=t;
a:=maxint;
repeat
j:=m;{倒退}
m:=abs(lt[j].l);
if lt[j].l<0 then x:=g[j,m].f-0;
if lt[j].l>0 then x:=g[m,j].c-g[m,j].f;
if a>x then a:=x;{找最大允許改進量}
until m=s;{直到源點}
ford:=false;
end;
procedure fulkerson(a:integer);
var
m,j:integer;
begin
m:=t;
repeat
j:=m;{從匯點相后推}
m:=abs(lt[j].l);
if lt[j].l<0 then g[j,m].f:=g[j,m].f-a{若為反相路,減去a);
if lt[j].l>0 then g[m,j].f:=g[m,j].f+a{否則,加上a};
until m=s{直到源點};
end;
procedure proceed;
var
i,j,x,del:integer;
success:boolean;
begin
s:=1;
inc(n,2);
t:=n;{引一個源點和一個匯點}
g1:=g;
fillchar(g,sizeof(g),0);
for i:=2 to n-1 do
for j:=2 to n-1 do
begin
g[s,i].c:=g[s,i].c+g1[j,i].b;{源點到任意一個節點的限制流為以該節點為終點的最小可行流之和}
g[i,t].c:=g[i,t].c+g1[i,j].b;{從任意一個節點到匯點的限制流為以該節點為起點的最小可行流之和}
end;
for i:=2 to n-1 do
for j:=2 to n-1 do
g[i,j].c:=g1[i,j].c-g1[i,j].b;{任意邊的限制流為最大可行流減去最小可行流}
g[2,n-1].c:=maxint;
g[n-1,2].c:=maxint;{原源點與匯點連一條限制流為無窮大的邊}
repeat
success:=ford(del);
if not success then fulkerson(del);
until success;{求新圖的最大流,即為原圖的可行流}
for i:=2 to n-1 do
for j:=2 to n-1 do
begin
g1[i,j].f:=g[i,j].f+g1[i,j].b;{恢復為實際可行流}
end;
s:=2;
dec(n);
t:=n;{欲求最小流,顛倒源匯點即可}
g:=g1;
g[s,t].f:=0;
g[t,s].f:=0;{恢復原圖}
repeat
success:=ford(del);
if not success then fulkerson(del);
until success;{求最大流}
end;
procedure out;
var
i,j:integer;
begin
for i:=1 to n do
begin
for j:=1 to n do
write(g[i,j].f);
writeln;
end;
end;{輸出}
begin
readg;
proceed;
out;
end.
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -