题目大意:给出很多个网络,求其最大流
输入:第一行N,M(0<=N<=200,2<=M<=200)
接下来的N行给出每一条边的起点、终点、流的上限
M为点数
输出:最大流的数值
很裸的一道最大流,不会的自己百度一下学习(会的话真的没有什么好说的,所以注释偏少)
代码:
const
maxn=1000;
maxm=100000;
maxw=2000000000;
type
gtype=record
x,y,f,c,next,op:longint;
end;
var
g:array[1..maxm*2] of gtype;
first,first1:array[1..maxn] of longint;
p,level,prt:array[1..maxn] of longint;
visited:array[1..maxn] of boolean;
n,m,tot,vs,vt,maxflow,temp,i,a,b,c:longint;
function min(a,b:longint):longint;
begin
if a<b then exit(a) else exit(b);
end;
procedure add(a,b,c:longint);
begin
inc(tot);
g[tot].x:=a;
g[tot].y:=b;
g[tot].c:=c;
g[tot].next:=first[a];
first[a]:=tot;
g[tot].op:=tot+1;
inc(tot);
g[tot].x:=b;
g[tot].y:=a;
g[tot].c:=0;
g[tot].next:=first[b];
first[b]:=tot;
g[tot].op:=tot-1; //准备反边
end;
procedure make_level;
var
i,f,r,temp,tp:longint;
begin
for i:=1 to n do level[i]:=maxw;
fillchar(p,sizeof(p),0);
f:=1; r:=1; p[f]:=vs; level[vs]:=1;
repeat
tp:=p[f];
if tp=vt then exit;
temp:=first[tp];
while temp<>-1 do
begin
if level[g[temp].y]>level[tp]+1 then
if (g[temp].f<g[temp].c) or ((g[temp].c=0) and (g[temp].f>0)) then
begin
inc(r);
p[r]:=g[temp].y;
level[g[temp].y]:=level[tp]+1;
end;
temp:=g[temp].next;
end;
inc(f);
until f>r;
end;
procedure dfs_maxflow;
var
top,mint,i,temp,tp,ti:longint;
begin
fillchar(p,sizeof(p),0);
fillchar(prt,sizeof(prt),0);
fillchar(visited,sizeof(visited),false);
first1:=first;
top:=1;
p[1]:=vs;
while top>0 do
begin
if p[top]=vt then
begin
mint:=maxw;
for i:=top downto 2 do
if g[prt[p[i]]].f<g[prt[p[i]]].c
then mint:=min(mint,g[prt[p[i]]].c-g[prt[p[i]]].f)
else
mint:=min(mint,g[prt[p[i]]].f);
for i:=top downto 2 do
if g[prt[p[i]]].f<g[prt[p[i]]].c then
begin
g[prt[p[i]]].f:=g[prt[p[i]]].f+mint;
g[g[prt[p[i]]].op].f:=g[g[prt[p[i]]].op].f+mint;
if g[prt[p[i]]].f=g[prt[p[i]]].c then ti:=i;
end
else
begin
g[prt[p[i]]].f:=g[prt[p[i]]].f-mint;
g[g[prt[p[i]]].op].f:=g[g[prt[p[i]]].op].f-mint;
if g[prt[p[i]]].f=0 then ti:=i;
end;
top:=ti-i;
end
else
begin
temp:=first1[p[top]];
tp:=p[top];
while temp<>-1 do
begin
if (not visited[g[temp].y]) and (level[g[temp].y]=level[tp]+1) then
if (g[temp].f<g[temp].c) or ((g[temp].c=0) and (g[temp].f>0)) then
begin
first1[p[top]]:=g[temp].next;
inc(top);
p[top]:=g[temp].y;
prt[p[top]]:=temp;
break;
end;
temp:=g[temp].next;
end;
if temp=-1 then
begin
visited[p[top]]:=true;
dec(top);
end;
end;
end;
end;
begin
while not eof do
begin
fillchar(g,sizeof(g),0);
readln(m,n);
fillchar(first,sizeof(first),$ff);
tot:=0;
for i:=1 to m do
begin
readln(a,b,c);
add(a,b,c); //建立网络
end;
vs:=1; vt:=n;
while true do
begin
make_level;
if level[vt]=maxw then break;
dfs_maxflow;
end; //Dinic
maxflow:=0;
temp:=first[vs];
while temp<>-1 do
begin
maxflow:=maxflow+g[temp].f;
temp:=g[temp].next;
end;
writeln(maxflow);
end;
end.