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

学了网络流之后发现这道题的图也是挺好构造的。 以

样例
3
1 7 5
11 2 2 3 1

为例:



先拆点。



每天都可以买最多 \(+\infty\) 张餐巾,单价为 \(p\)。给源点和所有的上半点连容量为 \(+\infty\),费用为 \(p\) 的有向边。除此之外,每天的新餐巾也可以免费送到下一天,连上相应的有向边。



第 \(i\) 天需要 \(r_i\) 张餐巾,即第 \(i\) 天的上半点会向下半点流出 \(r_i\) 张脏餐巾,费用为 \(0\)。这里要稍作处理,让上半点的 \(d_i\) 张脏餐巾流往汇点;为了补偿下半点,允许源点往下半点流 \(d_i\) 张免费的脏餐巾。之所以这么做,是因为我们要求上午用去的餐巾数为 \(d_i\),而不是要求下午不送洗的餐巾数为 \(d_i\)。



慢洗和快洗分别会向 \(m\) 天和 \(n\) 天后流出新餐巾,每天最多可以洗 \(+\infty\) 张,费用分别为 \(f\),\(s\)。在这里慢洗部由于太慢,最终无法派上用场。

这张图的最大流最小费用就是答案。

#include <cstdio>
#include <cstring>
#include <queue> inline int min(const int& a, const int& b){
return a < b ? a : b;
} const int MAXN = 4e3 + 19, MAXM = 8e4 + 19, INF = 0x3f3f3f3f; struct Edge{
int to, next, c, dist;
}edge[MAXM << 1]; int cnt = -1, head[MAXN]; inline void add(int from, int to, int c, int dist){
edge[++cnt].to = to;
edge[cnt].c = c;
edge[cnt].dist = dist;
edge[cnt].next = head[from];
head[from] = cnt;
} int N, p, m, f, n, s; int dist[MAXN], flow[MAXN], pre[MAXN]; int spfa(void){
std::queue<int>q; q.push(0);
std::memset(dist, 0x3f, sizeof dist); dist[0] = 0;
std::memset(flow, 0x3f, sizeof flow);
while(!q.empty()){
int node = q.front(); q.pop();
for(int i = head[node]; i != -1; i = edge[i].next)
if(edge[i].c && dist[edge[i].to] > dist[node] + edge[i].dist){
dist[edge[i].to] = dist[node] + edge[i].dist;
flow[edge[i].to] = min(flow[node], edge[i].c);
pre[edge[i].to] = i;
q.push(edge[i].to);
}
}
if(flow[N + N + 1] == 0x3f3f3f3f)
return 0;
return flow[N + N + 1];
} void edmondsKarp(long long& fee){
while(spfa()){
fee += (long long)flow[N + N + 1] * (long long)dist[N + N + 1];
for(int i = N + N + 1; i; i = edge[pre[i] ^ 1].to)
edge[pre[i]].c -= flow[N + N + 1], edge[pre[i] ^ 1].c += flow[N + N + 1];
}
} int main(){
std::memset(head, -1, sizeof head);
std::scanf("%d%d%d%d%d%d", &N, &p, &m, &f, &n, &s);
for(int d, i = 1; i <= N; ++i){
std::scanf("%d", &d);
add(i, N + N + 1, d, 0), add(N + N + 1, i, 0, 0);
add(0, i + N, d, 0), add(i + N, 0, 0, 0);
}
for(int i = 1; i <= N; ++i)
add(0, i, INF, p), add(i, 0, 0, -p);
for(int i = 1; i < N; ++i)
add(i, i + 1, INF, 0), add(i + 1, i, 0, 0);
for(int i = 1; i + m <= N; ++i)
add(i + N, i + m, INF, f), add(i + m, i + N, 0, -f);
for(int i = 1; i + n <= N; ++i)
add(i + N, i + n, INF, s), add(i + n, i + N, 0, -s);
long long ans = 0; edmondsKarp(ans);
printf("%lld\n", ans);
return 0;
}

LibreOJ #6008. 「网络流 24 题」餐巾计划的更多相关文章

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

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

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

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

  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 #6013. 「网络流 24 题」负载平衡 最小费用最大流 供应平衡问题

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

  7. LibreOJ #6000. 「网络流 24 题」搭配飞行员

    二次联通门 : LibreOJ #6000. 「网络流 24 题」搭配飞行员 /* LibreOJ #6000. 「网络流 24 题」搭配飞行员 二分图最大匹配 Dinic最大流 + 当前弧优化 */ ...

  8. LibreOJ #6014. 「网络流 24 题」最长 k 可重区间集

    #6014. 「网络流 24 题」最长 k 可重区间集 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   ...

  9. LIbreOJ #6011. 「网络流 24 题」运输问题 最小费用最大流

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

随机推荐

  1. vue基础总结

    Vue语法: new Vue({ //挂载: el: '#app', //初始化数据: data: {}, //监听 data 的数据变化: watch: { todos: { //深度监视 hand ...

  2. C++中map的介绍用法以及Gym题目:Two Sequences

    Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字(key),每个关键字只能在map中出现一次,第二个可能称为该关键字的值(value))的数据 处理能力,由于这个特性,它完成有可能 ...

  3. java 生成/解读 二维码

    package com.rails.util; import com.swetake.util.Qrcode; import jp.sourceforge.qrcode.QRCodeDecoder; ...

  4. JAVA(1)之关于对象数组作形参名的方法的使用

    public class Test{ int tour; public static void cs(Test a[]) { for (int i = 0; i < a.length; i++) ...

  5. 吴裕雄 python 神经网络——TensorFlow 多线程队列操作

    import tensorflow as tf queue = tf.FIFOQueue(100,"float") enqueue_op = queue.enqueue([tf.r ...

  6. Cisco AP-Sniffer模式空口抓包

     第一步:WLC/AP侧 配置AP为sniffer模式: 配置提交后,AP会重启,并且将不能发出SSID为clients提供服务. 第二步:一旦AP重新加入WLC,配置AP抓取的信道和抓取后的数据包发 ...

  7. golang的io.copy使用

    net/http 下载 在golang中,如果我们要下载一个文件,最简单的就是先用http.get()方法创建一个远程的请求后,后面可使用ioutil.WriteFile()等将请求内容直接写到文件中 ...

  8. KEAZ128 时钟配置

    本文介绍如何用KEAZ128评估版(FRDM-KEAZ128Q80)配置为40MHz core freqency/20MHz bus frequency. 1.了解器件时钟特性 参见NXP KEA12 ...

  9. 【协作式原创】查漏补缺之Go并发问题(单核多核)

    主要回答一下几个问题 1.单核并发问题 2.多核并发问题 2.几个不正确的同步案例 1.单核并发问题 先看一段go(1.11)代码: 单核CPU,1万个携程,每个携程执行100次+1操作, 思考n最终 ...

  10. Python回收机制

    1.小整数对象池 整数在程序中的使用非常广泛,python 为了优化速度,使用了小整数对象池,避免整数频繁申请和销毁和内存空间. Python 对小整数的定义事[-5, 257]这些整数对象的hi提前 ...