这类模板要求在所有的最大流中找出总费用最小的流量,最后输出费用。
思路:其实这类模板就是用最短路径找增广路,具体可见程序:
type
edge=record
tt,vol,cost,next:longint;
end;
const
INF=maxlongint shr 2;
var
q,a,pre,pos,dis:array[0..100000]of longint;
e:array[0..200000]of edge;
cost,flow,x,y,z,n,m,i,f,cnt,start,stop:longint;
vis:array[0..100000]of boolean;
function spfa(s,t:longint):boolean;
var
head,tail,now,i,adj:longint;
begin
fillchar(pre,sizeof(pre),$ff);
fillchar(vis,sizeof(vis),0);
head:=0;tail:=1;
fillchar(dis,sizeof(dis),$7f shr 2);
q[tail]:=s;
pre[s]:=s;
dis[s]:=0;
vis[s]:=true;
while head<>tail do
begin
head:=head+1;
now:=q[head];
vis[now]:=false;
i:=a[i];
while i>0 do
begin
adj:=e[i].tt;
if (e[i].vol>0)and(dis[now]+e[i].cost<dis[adj]) then
begin
dis[adj]:=dis[now]+e[i].cost;
pre[adj]:=now;
pos[adj]:=i;
if not vis[adj] then
begin
vis[adj]:=true;
tail:=tail+1;
q[tail]:=adj;
end;
end;
i:=e[i].next;
end;
end;
exit(pre[t]>-1);
end;
procedure insert(from,tt,vol,cost:longint);
begin
cnt:=cnt+1;
e[cnt].tt:=tt;
e[cnt].vol:=vol;
e[cnt].cost:=cost;
e[cnt].next:=a[from];
a[from]:=cnt;
end;
begin
readln(n,m);
for i:=1 to m do
begin
readln(x,y,z,cost);
insert(x,y,z,cost);
insert(y,x,0,-cost);
end;
readln(start,stop);
cost:=0;flow:=0;
while spfa(start,stop) do
begin
f:=INF;
i:=stop;
while i<>start do
begin
if (e[pos[i]].vol<f) then
f:=e[pos[i]].vol;
i:=pre[i];
end;
flow:=flow+f;
cost:=cost+dis[stop]*f;
i:=stop;
while i<>start do
begin
e[pos[i]].vol:=e[pos[i]].vol-f;
inc(e[pos[i]xor 1].vol,f);
end;
end;
write(cost);
end.