LibreOJ #6008. 「网络流 24 题」餐巾计划
这道题其实我在刚学 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 题」餐巾计划的更多相关文章
- LibreOJ #6008. 「网络流 24 题」餐巾计划 最小费用最大流 建图
#6008. 「网络流 24 题」餐巾计划 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 ...
- Libre 6008 「网络流 24 题」餐巾计划 (网络流,最小费用最大流)
Libre 6008 「网络流 24 题」餐巾计划 (网络流,最小费用最大流) Description 一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,-,N).餐厅可以从三种途径获得餐巾. ...
- LOJ #6008. 「网络流 24 题」餐巾计划
#6008. 「网络流 24 题」餐巾计划 题目描述 一个餐厅在相继的 n nn 天里,每天需用的餐巾数不尽相同.假设第 i ii 天需要 ri r_iri 块餐巾.餐厅可以购买新的餐巾,每块餐 ...
- [luogu_P1251][LOJ#6008]「网络流 24 题」餐巾计划
[luogu_P1251][LOJ#6008]「网络流 24 题」餐巾计划 试题描述 一个餐厅在相继的 \(N\) 天里,第 \(i\) 天需要 \(R_i\) 块餐巾 \((i=l,2,-,N)\) ...
- 【刷题】LOJ 6008 「网络流 24 题」餐巾计划
题目描述 一个餐厅在相继的 \(n\) 天里,每天需用的餐巾数不尽相同.假设第 \(i\) 天需要 \(r_i\) 块餐巾.餐厅可以购买新的餐巾,每块餐巾的费用为 \(P\) 分:或者把旧餐巾送到快洗 ...
- LibreOJ #6013. 「网络流 24 题」负载平衡 最小费用最大流 供应平衡问题
#6013. 「网络流 24 题」负载平衡 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 ...
- LibreOJ #6000. 「网络流 24 题」搭配飞行员
二次联通门 : LibreOJ #6000. 「网络流 24 题」搭配飞行员 /* LibreOJ #6000. 「网络流 24 题」搭配飞行员 二分图最大匹配 Dinic最大流 + 当前弧优化 */ ...
- LibreOJ #6014. 「网络流 24 题」最长 k 可重区间集
#6014. 「网络流 24 题」最长 k 可重区间集 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 ...
- LIbreOJ #6011. 「网络流 24 题」运输问题 最小费用最大流
#6011. 「网络流 24 题」运输问题 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 ...
随机推荐
- 【PAT甲级】1073 Scientific Notation (20 分)
题意: 输入科学计数法输出它表示的数字. AAAAAccepted code: #define HAVE_STRUCT_TIMESPEC #include<bits/stdc++.h> u ...
- 深入浅出Oracle:DBA入门、进阶与诊断案例 PDF 下载
网盘地址: 链接:https://pan.baidu.com/s/1tMFoNSUW7ICKOtmSQ5ZazA 提取码:dbnc
- 传奇脚本:#AutoRun NPC SEC 参数说明
传奇脚本:#AutoRun NPC SEC 参数说明 SEC:按秒运行MIN:按分运行HOUR:按小时运行DAY:按天运行RunOnDay:按每天什么时候运行RUNONWEEK:按星期几及时间运行机器 ...
- JAVA8-用lamda表达式和增强版Comparator进行排序
1.单条件升序: list.sort(Comparator.comparing(User::getId); 2.降序: list.sort(Comparator.comparing(User::get ...
- Sudo临时提权配置
目录 Sudo临时提权配置 参考 Sudo简介 Sudo配置文件 Sudo配置语法 Sudo配置实例 Sudo日志记录 Sudo临时提权配置
- leetCode练题——38. Count and Say
1.题目 38. Count and Say The count-and-say sequence is the sequence of integers with the first five te ...
- Python爬虫教程:requests模拟登陆github
1. Cookie 介绍 HTTP 协议是无状态的.因此,若不借助其他手段,远程的服务器就无法知道以前和客户端做了哪些通信.Cookie 就是「其他手段」之一. Cookie 一个典型的应用场景,就是 ...
- cmd添加管理员账号
net user 用户名 密码 /add net localgroup Administrators 用户名 /add
- ENTRYPOINT与CMD/实现切换用户执行
1.CMD 最终会被解析成:["cmd","arg1","arg2"] 可以在运行时被覆盖 2.ENTRYPOINT 最终解析成 [&quo ...
- 微权获取openid信授
(1)首页要有一个自己的微信测试号的appid和秘钥 (2)公司里都是后台传code(接口),获取openid(接口) 请求code接口:/Wechat/GetUserInfo/getCode //判 ...