LuoguP1251 餐巾计划问题(费用流)
题目描述
一个餐厅在相继的 NN 天里,每天需用的餐巾数不尽相同。假设第 ii 天需要 r_iri块餐巾( i=1,2,...,N)。餐厅可以购买新的餐巾,每块餐巾的费用为 pp 分;或者把旧餐巾送到快洗部,洗一块需 m 天,其费用为 f 分;或者送到慢洗部,洗一块需 nn天(n>mn>m),其费用为 ss 分(s<fs<f)。
每天结束时,餐厅必须决定将多少块脏的餐巾送到快洗部,多少块餐巾送到慢洗部,以及多少块保存起来延期送洗。但是每天洗好的餐巾和购买的新餐巾数之和,要满足当天的需求量。
试设计一个算法为餐厅合理地安排好 NN 天中餐巾使用计划,使总的花费最小。编程找出一个最佳餐巾使用计划。
输入输出格式
输入格式:
由标准输入提供输入数据。文件第 1 行有 1 个正整数 NN,代表要安排餐巾使用计划的天数。
接下来的 NN 行是餐厅在相继的 NN 天里,每天需用的餐巾数。
最后一行包含5个正整数p,m,f,n,sp,m,f,n,s。pp 是每块新餐巾的费用; mm 是快洗部洗一块餐巾需用天数; ff 是快洗部洗一块餐巾需要的费用; nn 是慢洗部洗一块餐巾需用天数; ss 是慢洗部洗一块餐巾需要的费用。
输出格式
将餐厅在相继的 N 天里使用餐巾的最小总花费输出
解题思路:
考虑一下流量问题,发现最大流已经确定了。
此时需要构造一个流使每天的流量都满足要求,
那么就应该在汇点附近约束。
所以需要让每天的餐巾指向汇点。
需要满足直接购买,所以连入新流通入餐巾流中。
考虑餐巾的来源还有洗,那么在前几天的废餐巾指向这个新餐巾。
而废餐巾每天的数量都是固定的,所以连源上就好了。
考虑到可能有余负,向下一天的餐巾连边
建图都讲了边权就不说了。
最后跑一遍费用流就好了。
代码:
- #include<queue>
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- typedef long long lnt;
- const lnt oo=0x3f3f3f3f3f3f3f3fll;
- struct pnt{
- int hd;
- int pre;
- int lst;
- lnt val;
- lnt dis;
- bool vis;
- }p[];
- struct ent{
- int twd;
- int lst;
- lnt vls;
- lnt dis;
- }e[];
- int cnt;
- int n,m;
- int s,t;
- int P,M,F,N,S;
- std::queue<int>Q;
- void ade(int f,int t,lnt v,lnt d)
- {
- cnt++;
- e[cnt].twd=t;
- e[cnt].vls=v;
- e[cnt].dis=d;
- e[cnt].lst=p[f].hd;
- p[f].hd=cnt;
- return ;
- }
- bool Spfa(void)
- {
- while(!Q.empty())Q.pop();
- for(int i=;i<=t;i++)
- {
- p[i].dis=p[i].val=oo;
- p[i].vis=false;
- }
- p[s].dis=;
- p[s].vis=true;
- p[t].pre=-;
- Q.push(s);
- while(!Q.empty())
- {
- int x=Q.front();
- Q.pop();
- p[x].vis=false;
- for(int i=p[x].hd;i;i=e[i].lst)
- {
- int to=e[i].twd;
- if(p[to].dis>p[x].dis+e[i].dis&&e[i].vls>)
- {
- p[to].dis=p[x].dis+e[i].dis;
- p[to].pre=x;
- p[to].val=std::min(p[x].val,e[i].vls);
- p[to].lst=i;
- if(p[to].vis)continue;
- p[to].vis=true;
- Q.push(to);
- }
- }
- }
- return p[t].pre!=-;
- }
- lnt Ek(void)
- {
- lnt ans=;
- while(Spfa())
- {
- ans+=p[t].dis*p[t].val;
- for(int i=t;i!=s;i=p[i].pre)
- {
- e[p[i].lst].vls-=p[t].val;
- e[((p[i].lst-)^)+].vls+=p[t].val;
- }
- }
- return ans;
- }
- int main()
- {
- // freopen("a.in","r",stdin);
- scanf("%d",&n);
- s=n*+;
- t=s+;
- for(int i=;i<=n;i++)
- {
- int v;
- scanf("%d",&v);
- ade(i,t,v,);
- ade(t,i,,);
- ade(s,i+n,v,);
- ade(i+n,s,,);
- }
- scanf("%d%d%d%d%d",&P,&M,&F,&N,&S);
- for(int i=;i<=n;i++)
- {
- ade(s,i,oo,P);
- ade(i,s,,-P);
- if(i+M<=n)
- {
- ade(i+n,i+M,oo,F);
- ade(i+M,i+n,,-F);
- }
- if(i+N<=n)
- {
- ade(i+n,i+N,oo,S);
- ade(i+N,i+n,,-S);
- }
- if(i+<=n)
- {
- ade(i,i+,oo,);
- ade(i+,i,,);
- }
- }
- printf("%lld\n",Ek());
- return ;
- }
LuoguP1251 餐巾计划问题(费用流)的更多相关文章
- 洛谷.1251.餐巾计划问题(费用流SPFA)
题目链接 /* 每一天的餐巾需求相当于必须遍历某些点若干次 设q[i]为Dayi需求量 (x,y)表示边x容y费 将每个点i拆成i,i',由i'->T连(q[i],0)的边,表示求最大流的话一定 ...
- P1251 餐巾计划问题 费用流
https://www.luogu.org/problemnew/show/P1251 题意 有一家酒店,酒店每天需要ri张桌布,桌布可以现买,p元.可以通过快洗店,等m天,f元.可以通过慢洗店,等n ...
- [luoguP1251] 餐巾计划问题(费用流)
传送门 模型 网络优化问题,用最小费用最大流解决. 实现 把每天分为二分图两个集合中的顶点Xi,Yi,建立附加源S汇T. 1.从S向每个Xi连一条容量为ri,费用为0的有向边. 2.从每个Yi向T连一 ...
- LibreOJ #6008. 「网络流 24 题」餐巾计划 最小费用最大流 建图
#6008. 「网络流 24 题」餐巾计划 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 ...
- Vijos1891 学姐的逛街计划 【费用流】*
Vijos1891 学姐的逛街计划 描述 doc 最近太忙了, 每天都有课. 这不怕, doc 可以请假不去上课. 偏偏学校又有规定, 任意连续 n 天中, 不得请假超过 k 天. doc 很忧伤, ...
- HDU 6118 2017百度之星初赛B 度度熊的交易计划(费用流)
度度熊的交易计划 Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- 【bzoj3291】Alice与能源计划 模拟费用流+二分图最大匹配
题目描述 在梦境中,Alice来到了火星.不知为何,转眼间Alice被任命为火星能源部长,并立刻面临着一个严峻的考验. 为了方便,我们可以将火星抽象成平面,并建立平面直角坐标系.火星上一共有N个居民点 ...
- 【HDOJ6118】度度熊的交易计划(费用流)
题意: 度度熊参与了喵哈哈村的商业大会,但是这次商业大会遇到了一个难题: 喵哈哈村以及周围的村庄可以看做是一共由n个片区,m条公路组成的地区. 由于生产能力的区别,第i个片区能够花费a[i]元生产1个 ...
- HDU 6118 度度熊的交易计划(费用流)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6118 [题目大意] 给出一张无向边权图,每个点最多可以生产b[i]商品,每件代价为a[i], 每个 ...
随机推荐
- Oracle的Clob转换类型
import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; imp ...
- centos通过yum安装jdk
安装之前先检查一下系统有没有自带open-jdk 命令: rpm -qa |grep java rpm -qa |grep jdk rpm -qa |grep gcj 如果没有输入信息表示没有安装. ...
- new期间的异常
new包含两步,调用operator new申请空间,以及调用构造函数. 如果第一步结束之后,第二步发生异常,需要归还第一步的空间. 编译器帮我们做了这件事情,并且会调用对应的delete. 另外 n ...
- UVa 11849 - CD
题目:给你两个有序序列(每一个序列中元素不同),求两序列中都出现的元素个数. 分析:简单题. 合并排序合并过程. 设置两个指针.指向两序列当前元素.那个元素小指针向后移动.相同大则计数加一,同一时候后 ...
- PostgreSQL数据库创建/删除
方法1 - 系统命令 sudo su - postgres #切换到postgres用户(系统用户) createdb weichen #创建数据库 psql #直接訪问数据库(默认进入本地postg ...
- 怎样给UINavigationBar加入button?
Mads Mobæk:给UINavigationBar加入button的演示样例代码 1 2 3 4 5 6 7 8 UIBarButtonItem *rightButton = [[UIBarBut ...
- STL 之 hash_map源代码剖析
// Filename: stl_hash_map.h // hash_map和hash_multimap是对hashtable的简单包装, 非常easy理解 /* * Copyright (c) 1 ...
- js创建dom操作select
document.getElementById("column-left").getElementsByTagName("header")[0].onclick ...
- Coderfroces 864 E. Fire(01背包+路径标记)
E. Fire http://codeforces.com/problemset/problem/864/E Polycarp is in really serious trouble — his h ...
- Linux下通过.desktop 文件创建桌面程序图标及文件编写方式(Desktop Entry文件概述)
Linux下通过.desktop 文件创建桌面程序图标及文件编写方式 1.Desktop Entry文件概述:在 Windows 平台上,用户可以通过点击位于桌面或菜单上的快捷方式轻松打开目标应用程序 ...