【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.
时间: 2024-10-14 01:54:40

【BZOJ1834】network 网络扩容(最大流,费用流)的相关文章

BZOJ 1834 ZJOI2010 network 网络扩容 Dinic+EK费用流

题目大意:给定一个n个点m条边的无向图,每条边有一个扩容费用c,代表每扩容1流量的花费,求最大流及将最大流扩大k的最小费用 第一问直接跑最大流 第二问将每条边的起始点向终点连接一条流量为正无穷.费用为c的边 然后将n向汇点连一条流量为ans+k 费用为0的边 跑最小费用最大流即可 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 5010 #

BZOJ 1834 ZJOI2010 network 网络扩展 Dinic+EK费用流

标题效果:给定一个n积分m无向图边,每一方有一个扩展的成本c.代表扩张1费用的交通,寻求最大流量和扩大的最大流量k最小成本 第一问直接运行的最大流量 第二个问题将是连接到一个流的末端每个边缘的起点是正无穷大.费用c缘 然后,n汇点被连接到流动ans+k 费用为0的边 跑最小费用最大流就可以 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 5

【最大流】【费用流】bzoj1834 [ZJOI2010]network 网络扩容

引用题解: 最大流+费用流. 第一问最大流即可. 第二问为“最小费用最大流”. 由题意,这一问的可转化为在上一问的“残量网络”上,扩大一些边的容量,使能从新的图中的最大流为k. 那么易得:对于还有剩余流量的边,走过他们的费用为0.而“增加流量”可变为:对残留网络上的每一条边建一条容量是∞费用是w的边.这表示从这些边走,每一流量的费用为w,这就符合题意了. 最后建一个超级源点,从超级源向1建一条容量为k,费用为0的边,就可进行最小费用最大流算法. #include<cstdio> #includ

bzoj 1834: [ZJOI2010]network 网络扩容 -- 最大流+费用流

1834: [ZJOI2010]network 网络扩容 Time Limit: 3 Sec  Memory Limit: 64 MB Description 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不扩容的情况下,1到N的最大流: 2. 将1到N的最大流增加K所需的最小扩容费用. Input 输入文件的第一行包含三个整数N,M,K,表示有向图的点数.边数以及所需要增加的流量. 接下来的M行每行包含四个整数u,v,C,W,表示一

bzoj1834: [ZJOI2010]network 网络扩容

努力看了很久样例一直过不了...然后各种输出中间过程啊巴拉巴拉弄了1h,没办法了...然后突然想到啊原来的边可以用啊为什么不用...于是A了...感人肺腑 #include<cstdio> #include<cstring> #include<queue> #include<iostream> #include<algorithm> using namespace std; #define rep(i,n) for(int i=1;i<=n

【BZOJ】1834: [ZJOI2010]network 网络扩容(最大流+费用流)

我又思考人生了T_T,nd的数组开小了,一直wa,调了一个小时才发现啊!!!!!我一直以为我的isap错了T_T,可是完全没错啊!!!! 这题其实第一个问很简单,跑一次最大流即可.第二个问就是在跑完最大流的残量网络上每条边都扩充容量为oo,费用为边的费用,然后设个超级源连一条容量为k的边到点1,再跑一次费用流即可. 理由很简单,自己想,我就不说了. #include <cstdio> #include <cstring> #include <cmath> #includ

[BZOJ 1834][ZJOI2010]network 网络扩容(费用流)

Description 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不扩容的情况下,1到N的最大流: 2. 将1到N的最大流增加K所需的最小扩容费用. Solution 先求出最大流maxflow 求最小扩容费用的话,对于每一条边,建一条容量为c费用为0的边,再建一条容量为INF费用为w的边 跑费用流求流入maxflow+k的费用 #include<iostream> #include<cstdio> #include

bzoj1834 ZJOI2010网络扩容(费用流)

给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用. 求: 1.在不扩容的情况下,1到N的最大流: 2.将1到N的最大流增加K所需的最小扩容费用. 其中\(n \le 1000,m \le 5000,k \le 10\) 网络流题,复杂度都是没用的了.... 第一问就是一个裸的最大流 现在我们考虑第二问QwQ 最小扩容费用,我们是不是可以对于原图中的\(u->v\)的边,添加一条\(u->v\),流量为\(inf\),费用为\(w\)的边,这样就可以实

[ZJOI2010]网络扩容 (最大流 + 费用流)

题目描述 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不扩容的情况下,1到N的最大流: 2. 将1到N的最大流增加K所需的最小扩容费用. 输入输出格式 输入格式: 输入文件的第一行包含三个整数N,M,K,表示有向图的点数.边数以及所需要增加的流量. 接下来的M行每行包含四个整数u,v,C,W,表示一条从u到v,容量为C,扩容费用为W的边. 输出格式: 输出文件一行包含两个整数,分别表示问题1和问题2的答案. 输入输出样例 输入样例#