线性规划与网络流10 餐巾计划问题

算法实现题 8-10 餐巾计划问题(习题 8-21)
?问题描述:
一个餐厅在相继的 N 天里,每天需用的餐巾数不尽相同。假设第 i 天需要 ri块餐巾(i=1,
2,…,N)。餐厅可以购买新的餐巾,每块餐巾的费用为 p 分;或者把旧餐巾送到快洗部,
洗一块需 m 天,其费用为 f 分;或者送到慢洗部,洗一块需 n 天(n>m),其费用为 s<f 分。
每天结束时,餐厅必须决定将多少块脏的餐巾送到快洗部,多少块餐巾送到慢洗部,以及多
少块保存起来延期送洗。但是每天洗好的餐巾和购买的新餐巾数之和,要满足当天的需求量。
试设计一个算法为餐厅合理地安排好 N 天中餐巾使用计划,使总的花费最小。
?编程任务:
编程找出一个最佳餐巾使用计划.
?数据输入:
由文件 input.txt 提供输入数据。文件第 1 行有 6 个正整数 N,p,m,f,n,s。N 是要安排餐巾
使用计划的天数;p 是每块新餐巾的费用;m 是快洗部洗一块餐巾需用天数;f 是快洗部洗
一块餐巾需要的费用;n 是慢洗部洗一块餐巾需用天数;s 是慢洗部洗一块餐巾需要的费用。
接下来的 N 行是餐厅在相继的 N 天里,每天需用的餐巾数。
?结果输出:
程序运行结束时,将餐厅在相继的 N 天里使用餐巾的最小总花费输出到文件 output.txt
中。
输入文件示例
输出文件示例
input.txt
output.txt
3 10 2 3 3 2
5
6
7
145

题解:

其实构图不难想,关键在于细节的处理-----边的容量设置

而且还要注意读题,题中说可以延期洗,所以应该从i到i+1连一条容量为inf的边,inf是因为有可能积淀了好几天

注意到这一点后,同理 i 向 i+t1+n 连边的容量也需要时inf,i+t2+n 的容量也是inf

其实这题和saveprint那题有点像,构图都是比较巧妙的

代码:

  1 uses math;
  2 const inf=maxlongint;
  3 type node=record
  4      from,go,next,v,c:longint;
  5      end;
  6 var e:array[0..2000000] of node;
  7     pre,head,q,d:array[0..1000000] of longint;
  8     v:array[0..1000000] of boolean;
  9     i,j,n,s,t,l,r,mincost,tot,p,t1,t2,p1,p2,x:longint;
 10 procedure ins(x,y,z,w:longint);
 11  begin
 12  inc(tot);
 13  with e[tot] do
 14   begin
 15   from:=x;go:=y;v:=z;c:=w;next:=head[x];head[x]:=tot;
 16   end;
 17  end;
 18 procedure insert(x,y,z,w:longint);
 19  begin
 20  ins(x,y,z,w);ins(y,x,0,-w);
 21  end;
 22 function spfa:boolean;
 23  var i,x,y:longint;
 24  begin
 25  fillchar(v,sizeof(v),false);
 26  for i:=s to t do d[i]:=inf;
 27  l:=0;r:=1;q[1]:=s;d[s]:=0;v[s]:=true;
 28  while l<r do
 29   begin
 30   inc(l);
 31   x:=q[l];v[x]:=false;
 32   i:=head[x];
 33   while i<>0 do
 34    begin
 35    y:=e[i].go;
 36    if (e[i].v<>0) and (d[x]+e[i].c<d[y]) then
 37     begin
 38     d[y]:=d[x]+e[i].c;
 39     pre[y]:=i;
 40     if not(v[y]) then
 41      begin
 42      v[y]:=true;
 43      inc(r);
 44      q[r]:=y;
 45      end;
 46     end;
 47    i:=e[i].next;
 48   end;
 49  end;
 50  exit(d[t]<>inf);
 51  end;
 52 procedure mcf;
 53  var i,tmp:longint;
 54  begin
 55  mincost:=0;
 56  while spfa do
 57   begin
 58   tmp:=inf;
 59   i:=pre[t];
 60   while i<>0 do
 61    begin
 62    tmp:=min(tmp,e[i].v);
 63    i:=pre[e[i].from];
 64    end;
 65   inc(mincost,tmp*d[t]);
 66   i:=pre[t];
 67   while i<>0 do
 68    begin
 69    dec(e[i].v,tmp);
 70    inc(e[i xor 1].v,tmp);
 71    i:=pre[e[i].from];
 72    end;
 73   end;
 74  end;
 75 procedure init;
 76  begin
 77  tot:=1;
 78  readln(n,p,t1,p1,t2,p2);
 79  s:=0;t:=2*n+1;
 80  for i:=1 to n do
 81   begin
 82   readln(x);
 83   insert(s,i,x,0);
 84   insert(s,i+n,x,p);
 85   insert(i+n,t,x,0);
 86   if i+1<=n then insert(i,i+1,inf,0);
 87   if i+t1<=n then insert(i,i+t1+n,inf,p1);
 88   if i+t2<=n then insert(i,i+t2+n,inf,p2);
 89   end;
 90  end;
 91 procedure main;
 92  begin
 93  mincost:=0;
 94  mcf;
 95  writeln(mincost);
 96  end;
 97 begin
 98  assign(input,'input.txt');assign(output,'output.txt');
 99  reset(input);rewrite(output);
100  init;
101  main;
102  close(input);close(output);
103 end.   
View Code
原文地址:https://www.cnblogs.com/zyfzyf/p/3843904.html