您的位置:首页 > 理论基础 > 计算机网络

算法模板——sap网络最大流 2(非递归+邻接表)

2015-02-09 16:31 453 查看
实现功能:同最大流 1

这里面主要是把前面的邻接矩阵改成了邻接表,相比之下速度大大提高——本人实测,当M=1000000 N=10000 时,暂且不考虑邻接矩阵会不会MLE,新的程序速度快了很多倍(我们家这个很弱的电脑上耗时0.3s);而当M=300000 N=10000时,优势更加明显(几乎是秒出),别的没了,尤其当遇到稀疏图的时候这样子是大大划算的!!!

type
point=^node;
node=record
g,w:longint;
next:point;
end;

var
i,j,k,l,m,n,tmp,ans,aug,mi,s,t:longint;
di,a:array[0..10005] of point;
pre,his,dis,vh:array[0..10005] of longint;
flag:boolean;p,jl:point;
function min(x,y:longint):longint;inline;
begin
if x<y then  min:=x else min:=y;
end;
function add(x,y,z:longint):longint;inline;
var p:point;
begin
new(p);p^.w:=z;p^.g:=y;
p^.next:=a[x];a[x]:=p;
end;
procedure op(x,y,z:longint);inline;
var p:point;
begin
p:=a[x];
while p<>nil do
begin
if (p^.g=y) and ((p^.w+z)>=0) then
begin
p^.w:=p^.w+z;
break;
end;
p:=p^.next;
end;
end;
begin
readln(n,m,s,t);
for i:=1 to n do a[i]:=nil;
for i:=1 to m do
begin
readln(j,k,l);
add(j,k,l);add(k,j,0);
end;
for i:=1 to n do di[i]:=a[i];
fillchar(dis,sizeof(dis),0);
fillchar(pre,sizeof(pre),0);
fillchar(his,sizeof(his),0);
fillchar(vh,sizeof(vh),0);
i:=s;vh[0]:=n;ans:=0;aug:=maxlongint;
while dis[s]<n do
begin
flag:=false;his[i]:=aug;
p:=a[i];
while p<>nil do
begin
if (p^.w>0) and (dis[i]=(dis[p^.g]+1)) then
begin
aug:=min(aug,p^.w);
pre[p^.g]:=i;di[i]:=p;
flag:=true;i:=p^.g;
if i=t then
begin
ans:=ans+aug;
while i<>s do
begin
tmp:=i;
i:=pre[i];
op(i,tmp,-aug);
op(tmp,i,aug);
end;
aug:=maxlongint;
end;
break;
end;
p:=p^.next;
end;
if flag then continue;
jl:=nil;mi:=n-1;
p:=a[i];
while p<>nil do
begin
if (p^.w>0) and (dis[p^.g]<mi) then
begin
jl:=p;mi:=dis[p^.g];
end;
p:=p^.next;
end;
di[i]:=jl;
dec(vh[dis[i]]);
if vh[dis[i]]=0 then break;
dis[i]:=mi+1;
inc(vh[dis[i]]);
if i<>s then
begin
i:=pre[i];
aug:=his[i];
end;
end;
writeln(ans);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: