您的位置:首页 > 理论基础 > 计算机网络

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

2017-03-05 16:38 232 查看

题意:给定一张有向图,每条边都有一个容量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.

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: