实现功能:同sap网络最大流
今天第一次学Dinic,感觉最大的特点就是——相当的白话,相当的容易懂,而且丝毫不影响复杂度,顶多也就是代码长个几行
主要原理就是每次用spfa以O(n)的时间复杂度预处理出层次图,然后像sap一样深搜一下,搞定。。。代码相当好懂
type
point=^node;
node=record
g,w:longint;
next,anti:point;
end;
var
i,j,k,l,m,n,s,t,ans:longint;
a:array[..] of point;
c,d:array[..] of longint;
function min(x,y:longint):longint;
begin
if x<y then min:=x else min:=y;
end;
procedure add(x,y,z:longint);
var p:point;
begin
new(p);p^.g:=y;p^.w:=z;p^.next:=a[x];a[x]:=p;
new(p);p^.g:=x;p^.w:=;p^.next:=a[y];a[y]:=p;
a[x]^.anti:=a[y];a[y]^.anti:=a[x];
end;
function spfa:boolean; //spfa预处理出层次图,同时检测连通性
var p:point;f,r:longint;
begin
fillchar(c,sizeof(c),);
d[]:=s;f:=;r:=;c[s]:=;
while f<r do
begin
p:=a[d[f]];
while p<>nil do
begin
if (p^.w<>) and (c[p^.g]=-) then
begin
c[p^.g]:=c[d[f]]+;
d[r]:=p^.g;
inc(r);
end;
p:=p^.next;
end;
inc(f);
end;
exit(c[t]<>-);
end;
function dfs(x,flow:longint):longint; //像sap一样的DFS么么哒
var p:point;k:longint;
begin
if x=t then exit(flow);
dfs:=;p:=a[x];
while p<>nil do
begin
if (p^.w<>) and ((c[x]+)=c[p^.g]) then
begin
k:=dfs(p^.g,min(flow-dfs,p^.w));
if p^.w<>maxlongint then dec(p^.w,k);
if p^.anti^.w<>maxlongint then inc(p^.anti^.w,k);
inc(dfs,k);if dfs=flow then exit;
end;
p:=p^.next;
end;
end;
begin
readln(m,n);s:=;t:=n;
for i:=s to t do a[i]:=nil;
for i:= to m do
begin
readln(j,k,l);
add(j,k,l);
end;
ans:=;
while spfa do inc(ans,dfs(s,maxlongint));
writeln(ans);
readln;
end.