bzoj1834

首先先跑裸的最大流,然后加边,在残余网络上跑费用流
比较水

  1 const max=1000000007;
  2 type node=record
  3        from,flow,cost,point,next:longint;
  4      end;
  5 
  6 var edge:array[0..100010] of node;
  7     w:array[0..30010] of longint;
  8     d,p,pre,cur,h,numh:array[0..10010] of longint;
  9     q:array[0..2000010] of longint;
 10     v:array[0..2010] of boolean;
 11     j,x,y,f,t,ans1,ans2,len,n,m,k,i:longint;
 12 
 13 function min(a,b:longint):longint;
 14   begin
 15     if a>b then exit(b) else exit(a);
 16   end;
 17 
 18 procedure add(x,y,f,w:longint);
 19   begin
 20     inc(len);
 21     edge[len].from:=x;
 22     edge[len].point:=y;
 23     edge[len].next:=p[x];
 24     edge[len].flow:=f;
 25     edge[len].cost:=w;
 26     p[x]:=len;
 27   end;
 28 
 29 function sap:longint;
 30   var tmp,x,q,u,i,j,f,neck:longint;
 31   begin
 32     sap:=0;
 33     fillchar(numh,sizeof(numh),0);
 34     fillchar(h,sizeof(h),0);
 35     numh[0]:=n;
 36     u:=1;
 37     while h[0]<n do
 38     begin
 39       if u=n then
 40       begin
 41         i:=1;
 42         j:=cur[i];
 43         neck:=i;
 44         f:=edge[j].flow;
 45         while i<>n do
 46         begin
 47           if edge[j].flow<f then
 48           begin
 49             f:=edge[j].flow;
 50             neck:=edge[j].from;
 51           end;
 52           i:=edge[j].point;
 53           j:=cur[i];
 54         end;
 55         i:=1;
 56         j:=cur[i];
 57         while i<>n do
 58         begin
 59           dec(edge[j].flow,f);
 60           inc(edge[j xor 1].flow,f);
 61           i:=edge[j].point;
 62           j:=cur[i];
 63         end;
 64         u:=neck;
 65         sap:=sap+f;
 66       end;
 67       q:=-1;
 68       i:=p[u];
 69       while i<>-1 do
 70       begin
 71         x:=edge[i].point;
 72         if (edge[i].flow>0) and (h[u]=h[x]+1) then
 73         begin
 74           q:=i;
 75           break;
 76         end;
 77         i:=edge[i].next;
 78       end;
 79       if q<>-1 then
 80       begin
 81         cur[u]:=i;
 82         x:=edge[i].point;
 83         pre[x]:=u;
 84         u:=x;
 85       end
 86       else begin
 87         dec(numh[h[u]]);
 88         if numh[h[u]]=0 then break;
 89         tmp:=n;
 90         i:=p[u];
 91         while i<>-1 do
 92         begin
 93           x:=edge[i].point;
 94           if edge[i].flow>0 then tmp:=min(tmp,h[x]);
 95           i:=edge[i].next;
 96         end;
 97         h[u]:=tmp+1;
 98         inc(numh[h[u]]);
 99         if u<>1 then u:=pre[u];
100       end;
101     end;
102   end;
103 
104 function spfa:boolean;
105   var f,r,i,x,y:longint;
106   begin
107     for i:=1 to n do
108       d[i]:=max;
109     d[0]:=0;
110     fillchar(v,sizeof(v),false);
111     fillchar(pre,sizeof(pre),255);
112     v[0]:=true;
113     f:=1;
114     r:=1;
115     q[1]:=0;
116     while f<=r do
117     begin
118       x:=q[f];
119       v[x]:=false;
120       i:=p[x];
121       while i<>-1 do
122       begin
123         y:=edge[i].point;
124         if edge[i].flow>0 then
125           if d[x]+edge[i].cost<d[y] then
126           begin
127             d[y]:=d[x]+edge[i].cost;
128             pre[y]:=i;
129             if not v[y] then
130             begin
131               v[y]:=true;
132               inc(r);
133               q[r]:=y;
134             end;
135           end;
136         i:=edge[i].next;
137       end;
138       inc(f);
139     end;
140     if d[n]>=max then exit(false) else exit(true);
141   end;
142 
143 procedure mincost;
144   var x,y,i,j,neck:longint;
145   begin
146     while spfa do
147     begin
148       i:=n;
149       neck:=max;
150       while i<>0 do
151       begin
152         j:=pre[i];
153         neck:=min(neck,edge[j].flow);
154         i:=edge[j].from;
155       end;
156       i:=n;
157       while i<>0 do
158       begin
159         j:=pre[i];
160         dec(edge[j].flow,neck);
161         inc(edge[j xor 1].flow,neck);
162         i:=edge[j].from;
163       end;
164       ans2:=ans2+d[n]*neck;
165     end;
166   end;
167 
168 begin
169   readln(n,m,k);
170   len:=-1;
171   fillchar(p,sizeof(p),255);
172   for i:=1 to m do
173   begin
174     readln(x,y,f,w[i]);
175     add(x,y,f,0);
176     add(y,x,0,0);
177   end;
178   ans1:=sap;
179   t:=len;
180   i:=0;
181   while i<=t do
182   begin
183     x:=edge[i].from;
184     y:=edge[i].point;
185     f:=w[i div 2+1];
186     add(x,y,max,f);
187     add(y,x,0,-f);
188     i:=i+2;
189   end;
190   add(0,1,k,0);
191   add(1,0,0,0);
192   mincost;
193   writeln(ans1,' ',ans2);
194 end.
195 
196  
View Code
原文地址:https://www.cnblogs.com/phile/p/4473102.html