最小费用流spfa最小费用路算法模板(pascal)

3.30:

这篇是以前写的,用的还是指针存图,今天又写了个代码,码风稍微好看点。

传送门:http://www.cnblogs.com/Currier/p/6648685.html

---------------------------------------------------一点也不华丽的分割线---------------------------------------------------------

最小费用最大流(洛谷可评测):

 1 program rrr(input,output);
 2 const
 3   inf=123456789;
 4 type
 5   pointer=^nodetype;
 6   nodetype=record
 7      t,c,w:longint;
 8      next,rev:pointer;
 9   end;
10 var
11   a,fre:array[0..5050]of pointer;
12   p:pointer;
13   dis,q,frv:array[0..5050]of longint;
14   v:array[0..5050]of boolean;
15   n,m,s,t,x,y,c,w,i,sum,f,ans,max:longint;
16 function min(a,b:longint):longint;
17 begin
18    if a<b then exit(a) else exit(b);
19 end;
20 procedure ins(x,y,c,w:longint);
21 begin
22    new(p);p^.t:=y;p^.c:=c;p^.w:=w;p^.next:=a[x];a[x]:=p;
23 end;
24 procedure add(x,y,c,w:longint);
25 begin
26    ins(x,y,c,w);ins(y,x,0,-w);
27    a[x]^.rev:=a[y];a[y]^.rev:=a[x];
28 end;
29 procedure spfa;
30 var
31   h,t:longint;
32 begin
33    for i:=1 to n do dis[i]:=inf;
34    fillchar(v,sizeof(v),false);
35    h:=0;t:=1;q[1]:=s;dis[s]:=0;v[s]:=true;
36    while h<>t do
37       begin
38          inc(h);if h>5000 then h:=1;
39          p:=a[q[h]];
40          while p<>nil do
41             begin
42                if (p^.c>0) and (dis[q[h]]+p^.w<dis[p^.t]) then
43                   begin
44                      dis[p^.t]:=dis[q[h]]+p^.w;
45                      frv[p^.t]:=q[h];fre[p^.t]:=p;
46                      if not v[p^.t] then
47                         begin
48                            inc(t);if t>5000 then t:=1;
49                            q[t]:=p^.t;v[p^.t]:=true;
50                         end;
51                   end;
52                p:=p^.next;
53             end;
54              v[q[h]]:=false;
55       end;
56 end;
57 begin
58    assign(input,'r.in');assign(output,'r.out');reset(input);rewrite(output);
59    readln(n,m,s,t);
60    for i:=1 to m do begin read(x,y,c,w);add(x,y,c,w); end;
61    ans:=0;max:=0;
62    while true do
63       begin
64          spfa;
65          if dis[t]=inf then break;
66          i:=t;f:=inf;
67          while i<>s do begin f:=min(f,fre[i]^.c);i:=frv[i]; end;
68          max:=max+f;
69          i:=t;sum:=0;
70          while i<>s do begin fre[i]^.c:=fre[i]^.c-f;fre[i]^.rev^.c:=fre[i]^.rev^.c+f;sum:=sum+fre[i]^.w;i:=frv[i]; end;
71          ans:=ans+sum*f;
72       end;
73    write(max,' ',ans);
74    close(input);close(output);
75 end.

 

posted @ 2017-02-10 19:50  Klaier  阅读(1060)  评论(0编辑  收藏  举报