【BZOJ1834】network 网络扩容(最大流,费用流)

题意:给定一张有向图,每条边都有一个容量C和一个扩容费用W。这里扩容费用是指将容量扩大1所需的费用。

求: 1、 在不扩容的情况下,1到N的最大流;

2、 将1到N的最大流增加K所需的最小扩容费用。

30%的数据中,N<=100
100%的数据中,N<=1000,M<=5000,K<=10

思路:RYZ作业

第一问最大流即可

第二问网上很多题解都是在第一问的残余网络上构图,但是根本不需要

考虑边(x,y,z,w)

有容量为z,费用为0的免费流量,有容量为INF,费用为w的扩容付费流量,连这两种边

又因为求的是最大流为ans1+k时的最小费用,所以需要建立一个新的源点,从n连一条容量为ans1+k,费用为0的边来限制流量

费用流经典模型之一(模板?)

 

  1 var head,vet,next,len1,len2,fan,x,y,z,w:array[1..200000]of longint;
  2     pre:array[1..200000,1..2]of longint;
  3     dis,gap,q:array[0..200000]of longint;
  4     inq:array[1..200000]of boolean;
  5     n,m,ans1,ans2,tot,i,src,source,s,k:longint;
  6 
  7 procedure add(a,b,c,d:longint);
  8 begin
  9  inc(tot);
 10  next[tot]:=head[a];
 11  vet[tot]:=b;
 12  len1[tot]:=c;
 13  len2[tot]:=d;
 14  head[a]:=tot;
 15 
 16  inc(tot);
 17  next[tot]:=head[b];
 18  vet[tot]:=a;
 19  len1[tot]:=0;
 20  len2[tot]:=-d;
 21  head[b]:=tot;
 22 end;
 23 
 24 function min(x,y:longint):longint;
 25 begin
 26  if x<y then exit(x);
 27  exit(y);
 28 end;
 29 
 30 function dfs(u,aug:longint):longint;
 31 var e,v,val,t,flow:longint;
 32 begin
 33  if u=src then exit(aug);
 34  e:=head[u]; flow:=0; val:=s-1;
 35  while e<>0 do
 36  begin
 37   v:=vet[e];
 38   if len1[e]>0 then
 39   begin
 40    if dis[u]=dis[v]+1 then
 41    begin
 42     t:=dfs(v,min(len1[e],aug-flow));
 43     len1[e]:=len1[e]-t;
 44     len1[fan[e]]:=len1[fan[e]]+t;
 45     flow:=flow+t;
 46     if dis[source]>=s then exit(flow);
 47     if aug=flow then break;
 48    end;
 49    val:=min(val,dis[v]);
 50   end;
 51   e:=next[e];
 52  end;
 53  if flow=0 then
 54  begin
 55   dec(gap[dis[u]]);
 56   if gap[dis[u]]=0 then dis[source]:=s;
 57   dis[u]:=val+1;
 58   inc(gap[dis[u]]);
 59  end;
 60  exit(flow);
 61 end;
 62 
 63 function maxflow:longint;
 64 var ans:longint;
 65 begin
 66  fillchar(gap,sizeof(gap),0);
 67  fillchar(dis,sizeof(dis),0);
 68  gap[0]:=s; ans:=0;
 69  while dis[source]<s do ans:=ans+dfs(source,maxlongint);
 70  exit(ans);
 71 end;
 72 
 73 function spfa:boolean;
 74 var t,u,e,v,i,w:longint;
 75 begin
 76  for i:=1 to s do
 77  begin
 78   dis[i]:=maxlongint>>1;
 79   inq[i]:=false;
 80  end;
 81  t:=0; w:=1; q[1]:=source; inq[source]:=true; dis[source]:=0;
 82  while t<w do
 83  begin
 84   inc(t); u:=q[t mod 3000];
 85   inq[u]:=false;
 86   e:=head[u];
 87   while e<>0 do
 88   begin
 89    v:=vet[e];
 90    if (len1[e]>0)and(dis[u]+len2[e]<dis[v]) then
 91    begin
 92     pre[v,1]:=u;
 93     pre[v,2]:=e;
 94     dis[v]:=dis[u]+len2[e];
 95     if not inq[v] then
 96     begin
 97      inc(w); q[w mod 3000]:=v; inq[v]:=true;
 98     end;
 99    end;
100    e:=next[e];
101   end;
102  end;
103  if dis[src]=maxlongint>>1 then exit(false);
104  exit(true);
105 end;
106 
107 procedure mcf;
108 var k,e,t:longint;
109 begin
110  k:=src; t:=maxlongint;
111  while k<>source do
112  begin
113   t:=min(t,len1[pre[k,2]]);
114   k:=pre[k,1];
115  end;
116  k:=src;
117  while k<>source do
118  begin
119   e:=pre[k,2];
120   len1[e]:=len1[e]-t;
121   len1[fan[e]]:=len1[fan[e]]+t;
122   ans2:=ans2+t*len2[e];
123   k:=pre[k,1];
124  end;
125 end;
126 
127 begin
128  assign(input,'bzoj1834.in'); reset(input);
129  assign(output,'bzoj1834.out'); rewrite(output);
130  readln(n,m,k);
131  for i:=1 to 200000 do
132   if i and 1=1 then fan[i]:=i+1
133    else fan[i]:=i-1;
134  for i:=1 to m do
135  begin
136   readln(x[i],y[i],z[i],w[i]);
137   add(x[i],y[i],z[i],w[i]);
138  end;
139 
140  source:=1; src:=n; s:=n;
141  ans1:=maxflow;
142  fillchar(head,sizeof(head),0);
143  tot:=0;
144  for i:=1 to m do
145  begin
146   add(x[i],y[i],z[i],0);
147   add(x[i],y[i],maxlongint,w[i]);
148  end;
149  write(ans1,' ');
150  inc(src); inc(s);
151  add(n,src,ans1+k,0);
152  while spfa do mcf;
153  write(ans2);
154  close(input);
155  close(output);
156 end.

 

posted on 2017-03-05 16:38  myx12345  阅读(129)  评论(0编辑  收藏  举报

导航