题目描述

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

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

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

我们知道,对于每一天,其实有两种状态:

一天开始状态,这个时候应该决定买多少新的餐巾数目,有没有从洗衣部送过来的东西

第一天结束,我们需要决定,是否需要对用过的餐巾进行封存,是否需要对把衣服送到两种洗衣部里面

那么很明显,一个点不能满足我们的需求,我们可以把点进行拆分,分成白天和晚上,对应有6种情况

我们需要从起点连接每个白天,流量限制,费用为p,代表这个的餐巾选择新购买的数目

从起点再连接每个点的晚上,流量限制为这一天所需的餐巾数目,代表这一天一定会产生这么多的用过的餐巾

从每天早上连接到汇点流量限制为这一天所需的餐巾数目,代表这白天一定会消耗这么多餐巾

由于可以把用过的餐巾存起来,我们把每个晚上的餐巾存到第二天从餐巾,流量为今天用的餐巾数目,费用为0

我们可以把餐巾送到快洗部,那么应该这天晚上的餐巾,送到洗完的那一天的早上,流量上限是INF(因为可能有以前存的衣服),费用为快洗部的费用

也可以把餐巾送到慢洗部,那么应该这天晚上的餐巾,送到洗完的那一天的早上,流量上限是INF(因为可能有以前存的衣服),费用为慢洗部的费用

注意拆点的话,可以把点拆成i和i+n

代码:

#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
#include<queue>
#define LL long long
using namespace std;
const LL N = 3e4+,M = 4e6+;
const LL INF = 0x3f3f3f3f;
LL ver[M],edge[M],cost[M],Next[M],head[N];
LL d[N],incf[N],pre[N],v[N],a[N];
LL n,k,tot,s,t,maxflow;
LL ans;
void add(LL x,LL y,LL z,LL c){
ver[++tot]=y,edge[tot]=z,cost[tot]=c;
Next[tot]=head[x],head[x]=tot; ver[++tot]=x,edge[tot]=,cost[tot]=-c;
Next[tot]=head[y],head[y]=tot;
}
bool spfa(){
queue<LL>q;
for (LL i=;i<=N;i++){
d[i]=INF;
}
memset(v,,sizeof(v));
q.push(s);
d[s]=;
v[s]=;
incf[s]=INF;
while(q.size()){
LL x=q.front();
v[x]=;
q.pop();
for (int i=head[x];i;i=Next[i]){
if(!edge[i])
continue;
int y=ver[i];
if (d[y]>d[x]+cost[i] && edge[i]>){
d[y]=d[x]+cost[i];
incf[y]=min(incf[x],edge[i]);
pre[y]=i;
if (!v[y])v[y]=,q.push(y);
}
}
}
if (d[t]==INF)return false;
return true;
}
void update(){
int x=t;
while(x!=s){
int i=pre[x];
edge[i]-=incf[t];
edge[i^]+=incf[t];
x=ver[i^];
}
maxflow+=incf[t];
ans+=d[t]*incf[t];
}
int main(){
LL q_day,q_w,s_day,s_w,p,
maxflow=;
ans=;
tot=;
scanf("%lld",&n);
s=*n+;
t=*n+;
for (LL i=;i<=n;i++){
scanf("%lld",&a[i]);
}
scanf("%lld%lld%lld%lld%lld",&p,&q_day,&q_w,&s_day,&s_w);
for (LL i=;i<=n;i++){
add(s,i,INF,p);
add(s,i+n,a[i],);
add(i,t,a[i],);
if (i<n)add(i+n,i+n+,INF,);
if (i+q_day<=n){
add(i+n,i+q_day,INF,q_w);
}
if (i+s_day<=n){
add(i+n,i+s_day,INF,s_w);
}
}
while(spfa())update();
printf("%lld\n",ans);
return ;
}

网络流24题 P1251 餐巾计划问题 拆点的更多相关文章

  1. Libre 6008 「网络流 24 题」餐巾计划 (网络流,最小费用最大流)

    Libre 6008 「网络流 24 题」餐巾计划 (网络流,最小费用最大流) Description 一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,-,N).餐厅可以从三种途径获得餐巾. ...

  2. LibreOJ #6008. 「网络流 24 题」餐巾计划 最小费用最大流 建图

    #6008. 「网络流 24 题」餐巾计划 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

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

    #6008. 「网络流 24 题」餐巾计划 题目描述 一个餐厅在相继的 n nn 天里,每天需用的餐巾数不尽相同.假设第 i ii 天需要 ri r_ir​i​​ 块餐巾.餐厅可以购买新的餐巾,每块餐 ...

  4. [luogu_P1251][LOJ#6008]「网络流 24 题」餐巾计划

    [luogu_P1251][LOJ#6008]「网络流 24 题」餐巾计划 试题描述 一个餐厅在相继的 \(N\) 天里,第 \(i\) 天需要 \(R_i\) 块餐巾 \((i=l,2,-,N)\) ...

  5. 【刷题】LOJ 6008 「网络流 24 题」餐巾计划

    题目描述 一个餐厅在相继的 \(n\) 天里,每天需用的餐巾数不尽相同.假设第 \(i\) 天需要 \(r_i\) 块餐巾.餐厅可以购买新的餐巾,每块餐巾的费用为 \(P\) 分:或者把旧餐巾送到快洗 ...

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

    这道题其实我在刚学 OI 的时候就在一本通上看见过,还记得上面写着"新餐巾一次性买完"之类的话.当时还很稚嫩(现在也是),想了好久,根本想不出来. 学了网络流之后发现这道题的图也是 ...

  7. Cogs 727. [网络流24题] 太空飞行计划(最大权闭合子图)

    [网络流24题] 太空飞行计划 ★★☆ 输入文件:shuttle.in 输出文件:shuttle.out 简单对比 时间限制:1 s 内存限制:128 MB [问题描述] W 教授正在为国家航天中心计 ...

  8. P4480 「BJWC2018」「网络流与线性规划24题」餐巾计划问题

    刷了n次用了奇淫技巧才拿到rk1,亥 这道题是网络流二十四题中「餐巾计划问题」的加强版. 于是怀着试一试的心情用费用流交了一发: 哇塞,过了9个点!(强烈谴责出题人用*造数据 下面是费用流解法简述: ...

  9. 【hjmmm网络流24题补全计划】

    本文食用方式 按ABC--分层叙述思路 可以看完一步有思路后自行思考 飞行员配对问题 题目链接 这可能是24题里最水的一道吧... 很显然分成两个集合 左外籍飞行员 右皇家飞行员 跑二分图最大匹配 输 ...

随机推荐

  1. “.Net 社区大会”(dotnetConf) 2018 Day 1 主题演讲

    Miguel de Icaza.Scott Hunter.Mads Torgersen三位大咖给大家带来了 .NET Core ,C# 以及 Xamarin的精彩内容: 6月份已经发布了.NET Co ...

  2. 微擎where范围查询in

    where sale_time in($todayStart,$todayEnd)

  3. ThinkPHP5.1 + tufanbarisyildirim 解析apk

    摘要 对于apk,我可以说只会安装,并不知道其中有什么内容需要记录下来.这次公司做一个关于电视机顶盒的项目.对于这个陌生的项目,刚开始真是一脸懵逼,完全不知道如何下手. 因为这类的项目完全没有接触过, ...

  4. django框架使用mysql步骤

    在创建好django项目的基础上来讲解使用orm框架 注意:首先在mysql中手动或者通过命令创建一个数据库,我先创建一个名为orm的数据库. 1:在项目文件夹中的settings.py文件中配置my ...

  5. 第一周 IP通信基础学习回顾

    这周的课程首先让我们学习了计算机网络概述,了解计算机网络的定义和功能分别是:资源共享,信息传输与集中处理,负载均衡与分布处理,综合信息服务.同时也对计算机网络的演进,计算机网络的分类,计算机网络的性能 ...

  6. Flink从入门到放弃(入门篇4) DataStreamAPI

    戳更多文章: 1-Flink入门 2-本地环境搭建&构建第一个Flink应用 3-DataSet API 4-DataSteam API 5-集群部署 6-分布式缓存 7-重启策略 8-Fli ...

  7. 剑指 offer 第一题: 二维数组中的查找

    打算写 图解剑指 offer 66 题 的系列文章,不知道大家有没有兴趣

  8. C#工具:加密解密帮助类

    using System; using System.IO; using System.Security.Cryptography; using System.Text; //加密字符串,注意strE ...

  9. 改行了,学C#

    C#数组: 定义方法 ]; ,]; //这个是二维数组 只有这一种定义方法,不像java有多种定义方法.等号前面在栈中初始化类型为一维数组类型(int[])或二维数组类型(int[,])的存储堆中地址 ...

  10. java爬虫系列第一讲-爬虫入门

    1. 概述 java爬虫系列包含哪些内容? java爬虫框架webmgic入门 使用webmgic爬取 http://ady01.com 中的电影资源(动作电影列表页.电影下载地址等信息) 使用web ...