网络流——餐巾计划问题

题目描述:

一个餐厅在相继的 NN 天里,每天需用的餐巾数不尽相同。假设第 ii 天需要 r_iri? 块餐巾( i=1,2,...,N)。餐厅可以购买新的餐巾,每块餐巾的费用为 pp 分;或者把旧餐巾送到快洗部,洗一块需 m 天,其费用为 f 分;或者送到慢洗部,洗一块需 nn天( n>mn>m ),其费用为 ss 分( s<fs<f )。

每天结束时,餐厅必须决定将多少块脏的餐巾送到快洗部,多少块餐巾送到慢洗部,以及多少块保存起来延期送洗。但是每天洗好的餐巾和购买的新餐巾数之和,要满足当天的需求量。

试设计一个算法为餐厅合理地安排好 NN 天中餐巾使用计划,使总的花费最小。编程找出一个最佳餐巾使用计划。



建模:

把每天分为二分图两个集合中的顶点Xi,Yi,建立附加源S汇T。从S向每个Xi连一条容量为ri,费用为0的有向边。从每个Yi向T连一条容量为ri,费用为0的有向边。从S向每个Yi连一条容量为无穷大,费用为p的有向边。从每个Xi向Xi+1(i+1<=N)连一条容量为无穷大,费用为0的有向边。从每个Xi向Yi+m(i+m<=N)连一条容量为无穷大,费用为f的有向边。从每个Xi向Yi+n(i+n<=N)连一条容量为无穷大,费用为s的有向边。求网络最小费用最大流,费用流值就是要求的最小总花费。

代码:

 1 #include<bits/stdc++.h>
 2 #define INF 2147483647
 3 #define LL long long
 4 using namespace std;
 5 queue<int> f;
 6     int n,m,m1,t1,m2,t2,len=-1,st,ed;
 7     struct node{int x,y,c,d,next;} a[100000];
 8     int b[100000],last[100000],pre[100000],pos[100000],p[100000];
 9     LL dis[100000];
10     bool bz[100000];
11 void ins(int x,int y,int c,int d)
12 {
13     a[++len].x=x;a[len].y=y;a[len].c=c;a[len].d=d;a[len].next=last[x];last[x]=len;
14     a[++len].x=y;a[len].y=x;a[len].c=0;a[len].d=-d;a[len].next=last[y];last[y]=len;
15 }
16 bool spfa()
17 {
18     memset(bz,true,sizeof(bz));
19     bz[st]=false;
20     memset(dis,63,sizeof(dis));
21     dis[st]=0;
22     p[st]=INF;
23     f.push(st);
24     while(!f.empty())
25     {
26         int x=f.front();
27         bz[x]=true;
28         for(int i=last[x];i>-1;i=a[i].next)
29         {
30             int y=a[i].y;
31             if(a[i].c>0&&dis[y]>dis[x]+a[i].d)
32             {
33                 dis[y]=dis[x]+a[i].d;
34                 pos[y]=x;
35                 pre[y]=i;
36                 p[y]=min(p[x],a[i].c);
37                 if(bz[y])
38                 {
39                     f.push(y);
40                     bz[y]=false;
41                 }
42             }
43         }
44         f.pop();
45     }
46     return dis[ed]<4557430888798830399;
47 }
48 LL flow()
49 {
50     LL ans=0;
51     while(spfa())
52     {
53         ans+=p[ed]*dis[ed];
54         for(int i=ed;i!=st;i=pos[i])
55         {
56             a[pre[i]].c-=p[ed];
57             a[pre[i]^1].c+=p[ed];
58         }
59     }
60     return ans;
61 }
62 int main()
63 {
64     int x;
65     scanf("%d",&n);
66     st=0,ed=2*n+1;
67     memset(last,-1,sizeof(last));
68     for(int i=1;i<=n;i++)
69     {
70         scanf("%d",&x);
71         ins(st,i,x,0);//每天晚上从起点获得x条脏餐巾
72         ins(i+n,ed,x,0);//每天白天,向汇点提供x条干净的餐巾,流满时表示第i天的餐巾够用
73     }
74     scanf("%d %d %d %d %d",&m,&t1,&m1,&t2,&m2);
75     for(int i=1;i<=n;i++)
76     {
77         if(i+1<=n) ins(i,i+1,INF,0);//每天晚上可以将脏餐巾留到第二天晚上
78         if(i+t1<=n) ins(i,i+n+t1,INF,m1);//每天晚上可以送去快洗部,在地i+t1天早上收到餐巾
79         if(i+t2<=n) ins(i,i+n+t2,INF,m2);//每天晚上可以送去慢洗部,在地i+t2天早上收到餐巾
80         ins(st,i+n,INF,m);//每天早上可以购买餐巾
81     }
82     printf("%lld",flow());
83 }

原文地址:https://www.cnblogs.com/71-111/p/9337769.html

时间: 2024-11-08 09:20:10

网络流——餐巾计划问题的相关文章

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

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

【网络流24题】餐巾计划(图解)

LOJ 6008[网络流24题]餐巾计划 题解 一张图片说明建图方法: 解说: 这种建图方法完美区分开了"脏餐巾"和"干净餐巾"两种餐巾. 每天一定会有r[i]个脏餐巾,所以源点向每天的"脏餐巾"(图上used)连边,容量r[i],费用是0.另外,前一天的脏餐巾也可以留到下一天再处理,所以每天的used点向下一天的used点连一条边,容量INF,费用是0. 每天会需要r[i]个干净餐巾,所以每天的"干净餐巾"向汇点连边(图上n

【网络流24题】餐巾计划问题(最小费用最大流)

[网络流24题]餐巾计划问题(最小费用最大流) 题面 COGS 洛谷上的数据范围更大,而且要开longlong 题解 餐巾的来源分为两种: ①新买的 ②旧的拿去洗 所以,两种情况分别建图 先考虑第一种 因为新买餐巾没有任何限制,并且随时可以买 所以直接从源点向每一天连边,容量为INF,费用为餐巾的价格 因为流要流出去,所以每个点向汇点连边,容量为每天的用量,费用为0 第二种,旧的拿去洗 首先考虑一下怎么算有多少旧的餐巾 每天用旧的餐巾的数量值一定的,不可能变多 因此从源点向这些点连边,容量为每天

LOJ #6008. 「网络流 24 题」餐巾计划

#6008. 「网络流 24 题」餐巾计划 题目描述 一个餐厅在相继的 n nn 天里,每天需用的餐巾数不尽相同.假设第 i ii 天需要 ri r_ir?i?? 块餐巾.餐厅可以购买新的餐巾,每块餐巾的费用为 P PP 分:或者把旧餐巾送到快洗部,洗一块需 M MM天,其费用为 F FF 分:或者送到慢洗部,洗一块需 N NN 天,其费用为 S SS 分(S<F S < FS<F). 每天结束时,餐厅必须决定将多少块脏的餐巾送到快洗部,多少块餐巾送到慢洗部,以及多少块保存起来延期送洗.

餐巾计划问题

餐巾计划问题 Time Limit: 1000 MS  Memory Limit: 65536 KB Description 一个餐厅在相继的N 天里,每天需用的餐巾数不尽相同.假设第i天需要ri块餐巾(i=1, 2,-,N).餐厅可以购买新的餐巾,每块餐巾的费用为p分:或者把旧餐巾送到快洗部, 洗一块需m天,其费用为f 分:或者送到慢洗部,洗一块需n 天(n>m),其费用为s< f 分. 每天结束时,餐厅必须决定将多少块脏的餐巾送到快洗部,多少块餐巾送到慢洗部,以及多 少块保存起来延期送洗.

【题解】餐巾计划问题

[题解]餐巾计划问题 orz argent 一定要注意不要调到题目里的坑里来了,要记得脱离实际(大雾). 建模方法:我觉得没什么好讲的,真的是灵感问题,此外,这个问题可以直接无源汇上下界网络流.但是我不会 graph LR 净1 --w=r,c=0--> T 净2 --w=r,c=0--> T 净3 --w=r,c=0--> T 净4 --w=r,c=0--> T S --w=r,c=p--> 净1 S --w=r,c=p--> 净2 S --w=r,c=p-->

AC日记——餐巾计划问题 洛谷 P1084

餐巾计划问题 思路: 氧气优化水过: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 4005 #define maxque 1000005 #define INF 0x7fffffff #define ll long long ll n,head[maxn],E[maxque],V[maxque],W[maxque],F[maxque]; ll pi,qt,qc,st,sc,s,t,cnt=1,day[maxn],

网络流24题 餐巾计划问题

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

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

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