题目大意:
下了大雨要排水,从一个点排到另一个点,中间有很多的小河流,每个河流有自己的流量,小流又有小流。。。求出最大排出多少水(n<200)
解题思路:
网络流的模板题,一个点到一个点的最大流量,网络流我打的是dinic,听说一般只要会这个就好了..
打法就是用搜索每次找出一条可以到达终点的路径,全部流量去减了最小路径的流量。
程序:
type
arr=record
k,data,next,ref:longint;
end;
const
maxn=200;
var
i,j,n,p,q,x,m,o,p1,p2,p3,dalta,maxflow:longint;
a:array [0..maxn*10] of arr;
aw,last,d,z,path:array [0..maxn*10] of longint;
flag:array [0..maxn*10] of boolean;
function min(x,y:longint):longint;
begin
if x<y then exit(x)
else exit(y);
end;
procedure add(p,q,x:longint);
begin
inc(o);
a[o].k:=q;
a[o].data:=x;
a[o].next:=last[p];
a[o].ref:=o+1;
last[p]:=o;
inc(o);
a[o].k:=p;
a[o].data:=0;
a[o].next:=last[q];
a[o].ref:=o-1;
last[q]:=o;
end;
procedure relax(p,q:longint);
begin
if aw[q]>aw[p]+1 then
begin
aw[q]:=aw[p]+1;
if not flag[q] then
begin
flag[q]:=true;
inc(p3);
inc(p2);
if p2>maxn*10 then p2:=1;
d[p2]:=q;
end;
end;
end;
function spfa:boolean;
var
i,j:longint;
begin
fillchar(flag,sizeof(flag),false);
fillchar(aw,sizeof(aw),10);
d[1]:=1;
aw[1]:=0;
flag[1]:=true;
p1:=1; p2:=1; p3:=1;
repeat
i:=last[d[p1]];
while i<>0 do
begin
if a[i].data>0 then relax(d[p1],a[i].k);
i:=a[i].next;
end;
flag[d[p1]]:=false;
dec(p3);
inc(p1);
if p1>maxn*10 then p1:=1;
until p3=0;
if aw[m]<99999 then exit(true) else exit(false);
end;
procedure work;
var
i,j,k:longint;
begin
z[0]:=1;
z[1]:=1;
repeat
k:=z[z[0]];
if k<>m then
begin
j:=last[k];
while (j<>0) and ((a[j].data=0) or (aw[a[j].k]<>aw[k]+1)) do j:=a[j].next;
if j>0 then
begin
path[z[0]]:=j;
inc(z[0]);
z[z[0]]:=a[j].k;
end else
begin
aw[k]:=999999;
dec(z[0]);
end;
end else
begin
dalta:=999999999;
for i:=1 to z[0]-1 do
dalta:=min(dalta,a[path[i]].data);
inc(maxflow,dalta);
for i:=z[0]-1 downto 1 do
begin
dec(a[path[i]].data,dalta);
inc(a[a[path[i]].ref].data,dalta);
if a[path[i]].data=0 then k:=i;
end;
z[0]:=k;
end;
until z[0]=0;
end;
begin
readln(n,m);
for i:=1 to n do
begin
readln(p,q,x);
add(p,q,x);
end;
maxflow:=0;
while spfa do work;
writeln(maxflow);
end.