【Codevs1237&网络流24题餐巾计划】(费用流)

题意:一个餐厅在相继的 N 天里,每天需用的餐巾数不尽相同。

假设第 i 天需要 ri块餐巾(i=1,2,…,N)。餐厅可以购买新的餐巾,每块餐巾的费用为 p 分;

或者把旧餐巾送到快洗部,洗一块需 m 天,其费用为 f 分;

或者送到慢洗部,洗一块需 n 天(n>m),其费用为 s<f 分。
每天结束时,餐厅必须决定将多少块脏的餐巾送到快洗部,多少块餐巾送到慢洗部,以及多少块保存起来延期送洗。

但是每天洗好的餐巾和购买的新餐巾数之和,要满足当天的需求量。
试设计一个算法为餐厅合理地安排好 N 天中餐巾使用计划,使总的花费最小。 
编程找出一个最佳餐巾使用计划。

思路:RYZ作业

费用流经典模型之一

BYVOID:

【建模方法】
把每天分为二分图两个集合中的顶点Xi,Yi,建立附加源S汇T。
1、从S向每个Xi连一条容量为ri,费用为0的有向边。
2、从每个Yi向T连一条容量为ri,费用为0的有向边。
3、从S向每个Yi连一条容量为无穷大,费用为p的有向边。
4、从每个Xi向Xi+1(i+1<=N)连一条容量为无穷大,费用为0的有向边。
5、从每个Xi向Yi+m(i+m<=N)连一条容量为无穷大,费用为f的有向边。
6、从每个Xi向Yi+n(i+n<=N)连一条容量为无穷大,费用为s的有向边。
求网络最小费用最大流,费用流值就是要求的最小总花费。
【建模分析】
这个问题的主要约束条件是每天的餐巾够用,而餐巾的来源可能是最新购买,也可能是前几天送洗,

今天刚刚洗好的餐巾。每天用完的餐巾可以选择送到快洗部或慢洗部,或者留到下一天再处理。
经过分析可以把每天要用的和用完的分离开处理,建模后就是二分图。

二分图X集合中顶点Xi表示第i天用完的餐巾,其数量为ri,所以从S向Xi连接容量为ri的边作为限制。

Y集合中每个点Yi则是第i天需要的餐巾,数量为ri,与T连接的边容量作为限制。

每天用完的餐巾可以选择留到下一天(Xi->Xi+1),不需要花费,

送到快洗部(Xi->Yi+m),费用为f,

送到慢洗部(Xi->Yi+n),费用为s。

每天需要的餐巾除了刚刚洗好的餐巾,还可能是新购买的(S->Yi),费用为p。

在网络上求出的最小费用最大流,满足了问题的约束条件(因为在这个图上最大流一定可以使与T连接的边全部满流,其他边只要有可行流就满足条件),

而且还可以保证总费用最小,就是我们的优化目标。

  1 var head,vet,next,len1,len2,fan:array[1..2100000]of longint;
  2     inq:array[1..5000]of boolean;
  3     q:array[0..5000]of longint;
  4     num,pre:array[1..5000,1..2]of longint;
  5     dis,a:array[1..5000]of longint;
  6     n,m,p1,m1,f1,n1,s1,ans,source,src,s,tot,i,j:longint;
  7
  8 function min(x,y:longint):longint;
  9 begin
 10  if x<y then exit(x);
 11  exit(y);
 12 end;
 13
 14 procedure add(a,b,c,d:longint);
 15 begin
 16  inc(tot);
 17  next[tot]:=head[a];
 18  vet[tot]:=b;
 19  len1[tot]:=c;
 20  len2[tot]:=d;
 21  head[a]:=tot;
 22
 23  inc(tot);
 24  next[tot]:=head[b];
 25  vet[tot]:=a;
 26  len1[tot]:=0;
 27  len2[tot]:=-d;
 28  head[b]:=tot;
 29 end;
 30
 31 function spfa:boolean;
 32 var u,e,v,i,t,w:longint;
 33 begin
 34  for i:=1 to s do
 35  begin
 36   dis[i]:=maxlongint>>1;
 37   inq[i]:=false;
 38  end;
 39  t:=0; w:=1; q[1]:=source; dis[source]:=0; inq[source]:=true;
 40  while t<w do
 41  begin
 42   inc(t); u:=q[t mod 5000]; inq[u]:=false;
 43   e:=head[u];
 44   while e<>0 do
 45   begin
 46    v:=vet[e];
 47    if (len1[e]>0)and(dis[u]+len2[e]<dis[v]) then
 48    begin
 49     dis[v]:=dis[u]+len2[e];
 50     pre[v,1]:=u;
 51     pre[v,2]:=e;
 52     if not inq[v] then
 53     begin
 54      inc(w); q[w mod 5000]:=v; inq[v]:=true;
 55     end;
 56    end;
 57    e:=next[e];
 58   end;
 59  end;
 60  if dis[src]=maxlongint>>1 then exit(false);
 61  exit(true);
 62 end;
 63
 64 procedure mcf;
 65 var k,e,t:longint;
 66 begin
 67  k:=src; t:=maxlongint;
 68  while k<>source do
 69  begin
 70   t:=min(t,len1[pre[k,2]]);
 71   k:=pre[k,1];
 72  end;
 73  k:=src;
 74  while k<>source do
 75  begin
 76   e:=pre[k,2];
 77   len1[e]:=len1[e]-t;
 78   len1[fan[e]]:=len1[fan[e]]+t;
 79   ans:=ans+t*len2[e];
 80   k:=pre[k,1];
 81  end;
 82 end;
 83
 84 begin
 85  assign(input,‘codevs1237.in‘); reset(input);
 86  assign(output,‘codevs1237.out‘); rewrite(output);
 87  readln(n,p1,m1,f1,n1,s1);
 88  for i:=1 to 2100000 do
 89   if i and 1=1 then fan[i]:=i+1
 90    else fan[i]:=i-1;
 91  for i:=1 to n do read(a[i]);
 92  for i:=1 to n do
 93   for j:=1 to 2 do
 94   begin
 95    inc(s); num[i,j]:=s;
 96   end;
 97  source:=s+1; src:=s+2; s:=s+2;
 98  for i:=1 to n do add(source,num[i,1],a[i],0);
 99  for i:=1 to n do add(num[i,2],src,a[i],0);
100  for i:=1 to n-1 do add(num[i,1],num[i+1,1],maxlongint,0);
101  for i:=1 to n do add(source,num[i,2],maxlongint,p1);
102  for i:=1 to n do
103   if i+m1<=n then add(num[i,1],num[i+m1,2],maxlongint,f1);
104  for i:=1 to n do
105   if i+n1<=n then add(num[i,1],num[i+n1,2],maxlongint,s1);
106  while spfa do mcf;
107  writeln(ans);
108  close(input);
109  close(output);
110 end.
时间: 2024-12-25 16:37:58

【Codevs1237&网络流24题餐巾计划】(费用流)的相关文章

[网络流24题] 餐巾计划问题 [费用流]

题面: https://www.luogu.org/problemnew/show/P1251 思路: 这道题乍一看,可以跑上下界费用流 代码量.难度 -> inf 其实不然,我们可以用费用流的特殊处理去掉下界 观察题目,每天要求有ri块餐巾 首先,有贪心如下: 当且仅当每天可供使用的餐巾正好满足需求时,可以有最小费用 证明:若某一天有多一块餐巾,则其根本来源一定是买多了,而且在这块餐巾参与的周转中还消费了一些清洗费用,同时它造成其余的日子里也会有餐巾被闲置 因此首先把题目转化为"每天正好

餐巾计划问题 【网络流24题】【费用流】【zkw】

题目描述 一个餐厅在相继的 NN 天里,每天需用的餐巾数不尽相同.假设第 ii 天需要 r_iri?块餐巾( i=1,2,...,N).餐厅可以购买新的餐巾,每块餐巾的费用为 pp 分;或者把旧餐巾送到快洗部,洗一块需 m 天,其费用为 f 分;或者送到慢洗部,洗一块需 nn 天(n>mn>m),其费用为 ss 分(s<fs<f). 每天结束时,餐厅必须决定将多少块脏的餐巾送到快洗部,多少块餐巾送到慢洗部,以及多少块保存起来延期送洗.但是每天洗好的餐巾和购买的新餐巾数之和,要满足当

BZOJ 1221 HNOI 2001 软件开发/网络流24题 餐巾计划问题 最小费用最大流

题目大意:有一个软件公司,每天需要给一些员工准备消毒毛巾,这些毛巾可以循环利用,但是需要消毒.可以将毛巾送去消毒,有两种方式,A天fA花费,B天fB花费.或者还可以直接买新毛巾,问为了满足员工的需求,至少需要花多少钱. 思路:经典的费用流问题.将每一天拆点,S向每一天<<1连边,约束每一天需要多少毛巾:每一天<<1|1向T连边,约束每一天需要的毛巾.每一天<<1向这一天清洗的毛巾能够使用的那一天<<1|1,注意A和B.毛巾可以延后使用,那么每一天<&l

【COGS 461】[网络流24题] 餐巾 最小费用最大流

既然是最小费用最大流我们就用最大流来限制其一定能把每天跑满,那么把每个表示天的点向T连流量为其所需餐巾,费用为0的边,然后又与每天的餐巾对于买是无限制的因此从S向每个表示天的点连流量为INF,费用为一个餐巾的费用的边,然后我们考虑怎么用旧餐巾,我们用旧餐巾,要既不影响本点流量,也不影响本点费用,因此我们在开一坨点表示其对应得那天的旧餐巾,并通过他向离他快洗和离他慢洗天数的天的点连边,流量为Inf,费用为快洗.慢洗的费用,然后对于多余的旧餐巾,我们在一排天点中间从第一天连续地连到最后一天,流量为I

网络流24题 餐巾计划问题

题目描述 一个餐厅在相继的 N 天里,每天需用的餐巾数不尽相同.假设第 i 天需要 ri块餐巾(i=1,2,…,N).餐厅可以购买新的餐巾,每块餐巾的费用为 p 分:或者把旧餐巾送到快洗部,洗一块需 m 天,其费用为 f 分:或者送到慢洗部,洗一块需 n 天(n>m),其费用为 s<f 分.每天结束时,餐厅必须决定将多少块脏的餐巾送到快洗部,多少块餐巾送到慢洗部,以及多少块保存起来延期送洗.但是每天洗好的餐巾和购买的新餐巾数之和,要满足当天的需求量.试设计一个算法为餐厅合理地安排好 N 天中餐

[网络流24题] 餐巾计划

https://www.luogu.org/problemnew/show/1251 样例的构图: #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define N 4005 #define M 12001 const int inf=1e17; typedef long long LL; int tot=1; in

网络流24题-运输问题(费用流)

题目描述 WW 公司有 mm 个仓库和 nn 个零售商店.第 ii 个仓库有 a_iai? 个单位的货物:第 jj 个零售商店需要 b_jbj? 个单位的货物. 货物供需平衡,即\sum\limits_{i=1}^{m}a_i=\sum\limits_{j=1}^{n}b_ji=1∑m?ai?=j=1∑n?bj?. 从第 ii 个仓库运送每单位货物到第 jj 个零售商店的费用为 c_{ij}cij??? . 试设计一个将仓库中所有货物运送到零售商店的运输方案,使总运输费用最少. 输入输出格式 输

网络流(费用流):[网络流24题] 餐巾

[网络流24题] 餐巾 [问题描述] 一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,…,N).餐厅可以从三种途径获得餐巾. (1)购买新的餐巾,每块需p分: (2)把用过的餐巾送到快洗部,洗一块需m天,费用需f分(f<p).如m=l时,第一天送到快洗部的餐巾第二天就可以使用了,送慢洗的情况也如此. (3)把餐巾送到慢洗部,洗一块需n天(n>m),费用需s分(s<f). 在每天结束时,餐厅必须决定多少块用过的餐巾送到快洗部,多少块送慢洗部.在每天开始时,餐厅必须决定是否购买新餐

CGOS461 [网络流24题] 餐巾(最小费用最大流)

题目这么说的: 一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,…,N).餐厅可以从三种途径获得餐巾. 购买新的餐巾,每块需p分: 把用过的餐巾送到快洗部,洗一块需m天,费用需f分(f<p).如m=l时,第一天送到快洗部的餐巾第二天就可以使用了,送慢洗的情况也如此. 把餐巾送到慢洗部,洗一块需n天(n>m),费用需s分(s<f). 在每天结束时,餐厅必须决定多少块用过的餐巾送到快洗部,多少块送慢洗部.在每天开始时,餐厅必须决定是否购买新餐巾及多少,使洗好的和新购的餐巾之和满足当