ZJOI2010网络扩容

无限orz hzwer神牛……

第一问很简单,按数据建图,然后一遍最大流算法即可。
    第二问则需要用最小费用最大流算法,主要是建图,那么可以从第一问的残留网络上继续建图,对残留网络上的每一条边建一条容量是∞费用是w的边(反向弧容量为0,费用为-w),然后建一个超级源点,从超级源向1建一条容量为k,费用为0的边,对这个图进行最小费用最大流算法。
    最小费用最大流操作:
    1.首先要对于这道题的图来说,有的边需要花费费用,而有的又不用,而不用扩容的边费用为0,需要扩容的边费用为w,容量无限,这就是本题这样建图的原因。
    2.对于残留网络进行费用最短路SPFA算法,不用扩容的边一定会选费用为0的边,然后记录路径,找最小容量对可行路进行增流,更新ans
——hzwer
  1 uses math;
  2 const inf=maxlongint;
  3 type node=record
  4      from,go,v,c,t,next:longint;
  5      end;
  6 var  i,n,m,k,t,u,v,w,c,s,cnt,ans:longint;
  7      q,first,from,h,cur,d:array[0..10000] of longint;
  8      e:array[0..50000] of node;
  9 procedure ins(u,v,w,c:longint);
 10  begin
 11    inc(cnt);
 12    e[cnt].go:=v;e[cnt].from:=u;
 13    e[cnt].v:=w;e[cnt].t:=c;
 14    e[cnt].next:=first[u];first[u]:=cnt;
 15  end;
 16 procedure insert(u,v,w,c:longint);
 17  begin
 18    ins(u,v,w,c);ins(v,u,0,-c);
 19  end;
 20 procedure ins2(u,v,w,c:longint);
 21  begin
 22    inc(cnt);
 23    e[cnt].go:=v;e[cnt].from:=u;
 24    e[cnt].v:=w;e[cnt].c:=c;
 25    e[cnt].next:=first[u];first[u]:=cnt;
 26  end;
 27 procedure insert2(u,v,w,c:longint);
 28  begin
 29    ins2(u,v,w,c);ins2(v,u,0,-c);
 30  end;
 31 function bfs:boolean;
 32  var head,tail,i,x,y:longint;
 33    begin
 34      head:=0;tail:=1;fillchar(h,sizeof(h),0);
 35      q[1]:=s;h[s]:=1;
 36      while head<tail do
 37       begin
 38         inc(head);
 39         x:=q[head];
 40         i:=first[x];
 41         while i<>0 do
 42          begin
 43            y:=e[i].go;
 44            if (e[i].v<>0) and (h[y]=0) then
 45             begin
 46               h[y]:=h[x]+1;
 47               inc(tail);
 48               q[tail]:=y;
 49             end;
 50            i:=e[i].next;
 51          end;
 52       end;
 53    exit(h[t]<>0);
 54    end;
 55 function dfs(x,f:longint):longint;
 56  var  i,tmp,used,y:longint;
 57    begin
 58    if x=t then exit(f);
 59    tmp:=0;used:=0;
 60    i:=cur[x];
 61    while i<>0 do
 62      begin
 63       y:=e[i].go;
 64       if (e[i].v<>0) and (h[y]=h[x]+1) then
 65        begin
 66          tmp:=dfs(y,min(f-used,e[i].v));
 67          dec(e[i].v,tmp);
 68          inc(e[i xor 1].v,tmp);
 69          inc(used,tmp);
 70          if e[i].v<>0 then cur[x]:=i;
 71          if used=f then exit(f);
 72        end;
 73       i:=e[i].next;
 74      end;
 75    if used=0 then h[x]:=-1;
 76    exit(used);
 77    end;
 78 procedure dinic;
 79  begin
 80    while bfs do
 81     begin
 82       for i:=1 to n do cur[i]:=first[i];
 83       inc(ans,dfs(s,inf));
 84     end;
 85  end;
 86 procedure build;
 87  var tmp:longint;
 88  begin
 89  tmp:=cnt;
 90  for i:=2 to cnt do
 91    if i and 1=0 then insert2(e[i].from,e[i].go,inf,e[i].t);
 92  end;
 93 function spfa:boolean;
 94  var i,x,y,head,tail:longint;
 95       v:array[0..10000] of boolean;
 96    begin
 97     head:=0;tail:=1;
 98     for i:=1 to n do d[i]:=inf;
 99     fillchar(v,sizeof(v),false);
100     q[1]:=0;d[0]:=0;v[i]:=true;
101     while head<tail do
102      begin
103       inc(head);
104       x:=q[head]; v[x]:=false;
105       i:=first[x];
106       while i<>0 do
107        begin
108         y:=e[i].go;
109         if (e[i].v>0) and (d[x]+e[i].c<d[y]) then
110          begin
111            d[y]:=d[x]+e[i].c;
112            from[y]:=i;
113            if not(v[y]) then
114             begin
115               inc(tail);
116               q[tail]:=y;
117               v[y]:=true;
118             end;
119          end;
120         i:=e[i].next;
121        end;
122      end;
123    exit(d[n]<>inf);
124    end;
125 procedure mcf;
126  var i,x:longint;
127    begin
128    x:=inf;
129    i:=from[n];
130    while i<>0 do
131      begin
132       x:=min(x,e[i].v);
133       i:=from[e[i].from];
134      end;
135    i:=from[n];
136    while i<>0 do
137      begin
138       dec(e[i].v,x);
139       inc(e[i xor 1].v,x);
140       i:=from[e[i].from];
141      end;
142    inc(ans,x*d[n]);
143    end;
144 procedure main;
145  begin
146    cnt:=1;
147    readln(n,m,k);
148    for i:=1 to m do
149     begin
150       readln(u,v,w,c);
151       insert(u,v,w,c);
152     end;
153    ans:=0;
154    s:=1;t:=n;
155    dinic;
156    write(ans,' ');
157    ans:=0;
158    build;
159    ins(0,1,k,0);
160    while spfa do mcf;
161    writeln(ans);
162  end;
163 begin
164   main;
165 end.           
View Code
原文地址:https://www.cnblogs.com/zyfzyf/p/3801253.html