2023.1.13 [网络流24题] 餐巾计划问题 LuoguP1251
2023.1.13
今日完成的[餐巾计划问题],是一道最小费用最大流的模板题,本人太弱在第一次使用dinic + spfa 完成此题时,也出现了许多问题,在此总结和提醒。
大致题意
一个餐厅在相继的 N 天里,每天需用的餐巾数不尽相同。假设第 i 天需要 \(r_i\)块餐巾( i=1,2,...,N)。餐厅可以购买新的餐巾,每块餐巾的费用为 p 分;或者把旧餐巾送到快洗部,洗一块需 m 天,其费用为 f 分;或者送到慢洗部,洗一块需 n 天(n>m),其费用为 s 分(s<f)。
每天结束时,餐厅必须决定将多少块脏的餐巾送到快洗部,多少块餐巾送到慢洗部,以及多少块保存起来延期送洗。但是每天洗好的餐巾和购买的新餐巾数之和,要满足当天的需求量。
试设计一个算法为餐厅合理地安排好 N 天中餐巾使用计划,使总的花费最小。编程找出一个最佳餐巾使用计划。
思路整理
需要餐巾尽量多的情况下费用尽量少,考虑向网络流转化。考虑把每一天视为一个点即可以完成转移。脏餐巾可以向m/n天后转移,干净的餐巾会在使用的这一天转移为脏餐巾。
通过上文我们可以发现,对于每一天的餐巾,我们可以把它分为干净和脏,两个状态,所以一天就被拆成了两个点,转移如下:
1.一天的脏餐巾流向n天后的干净餐巾,容量inf,边权p(n + i <= N)
2.一天的脏餐巾流向m天后的干净餐巾,容量inf,边权s(m + i <= N)
3.一天的脏餐巾流向明天的脏餐巾,容量inf,边权0(i + 1 <= N)
那么问题来了,我们怎么体现出“使用餐巾”、“购买餐巾”的过程呢?
时刻不要忘记网络流中源点和汇点的作用
4.每一天源点流向脏餐巾,容量\(r_i\),边权0,干净餐巾流向汇点,容量\(r_i\),边权为0
5.每一天源点流向干净餐巾,容量inf,边权p
原理:因为所跑是最大流,所以会尽量增多餐巾;而每天向汇点的流又是受限制的,就会刚好流\(r_i\)块餐巾;每次找的又是最短增广路,所以做法正确性得以证明,由于网络流算法时间较不稳定,理论时间复杂度是O($n ^ 2 $ m)
Code
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 5,inf = 0x7fffffff;
struct Edge{
int v,w,c,next;
}e[N * 2];
int n,d[N],vis[N],a[N],head[N],p,m,f,q,s,S,T,ans = 0,tot = 1;//1~n干净、n + 1~2n脏
inline void add(int x,int y,int c,int z)
{
++tot;
e[tot].v = y;
e[tot].w = z;
e[tot].c = c;
e[tot].next = head[x];
head[x] = tot;
}
inline bool spfa()
{
memset(vis,0,sizeof(vis));
for(int i=0;i<=T;i++) d[i] = inf / 2;
queue<int> q;
q.push(S);
vis[S] = 1;
d[S] = 0;
while(!q.empty())
{
int now = q.front();
q.pop();
vis[now] = 0;
for(int i = head[now];i;i = e[i].next)
{
int to = e[i].v;
if(e[i].c <= 0) continue;
if(d[to] > d[now] + e[i].w)
{
d[to] = d[now] + e[i].w;
if(!vis[to])
{
vis[to] = 1;
q.push(to);
}
}
}
}
if(d[T] < inf / 2)
return 1;
return 0;
}
inline int dinic(int x,int flow)
{
if(x == T) return flow;
int rest = flow;
vis[x] = 1;
for(int i = head[x];i && rest;i = e[i].next)
{
int to = e[i].v;
if(e[i].c <= 0 || d[to] != d[x] + e[i].w || vis[to]) continue;
int k = dinic(to,min(rest,e[i].c));
if(!k) d[to] = inf / 2;
e[i].c -= k;
rest -= k;
e[i ^ 1].c += k;
ans += k * e[i].w;
}
return flow - rest;
}
signed main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
cin>>p>>m>>f>>q>>s;
S = 0,T = 2 * n + 1;
for(int i=1;i<=n;i++)
{
add(S,i + n,a[i],0);
add(i + n,S,0,0);
add(i,T,a[i],0);
add(T,i,0,0);
add(S,i,a[i],p);
add(i,S,0,-p);
if(i + m <= n)
{
add(i + n,i + m,inf,f);
add(i + m,i + n,0,-f);
}
if(i + q <= n)
{
add(i + n,i + q,inf,s);
add(i + q,i + n,0,-s);
}
if(i + n + 1 <= n * 2)
{
add(i + n,i + n + 1,inf,0);
add(i + n + 1,i + n,0,0);
}
}
int flow = 0;
while(spfa())
{
memset(vis,0,sizeof(vis));
while(flow = dinic(S,inf / 2))
{
memset(vis,0,sizeof(vis));
flow = 0;
}
}
cout<<ans;
return 0;
}
2023.1.13 [网络流24题] 餐巾计划问题 LuoguP1251的更多相关文章
- 网络流24题 餐巾计划(DCOJ8008)
题目描述 一个餐厅在相继的 n nn 天里,每天需用的餐巾数不尽相同.假设第 i ii 天需要 ri r_iri 块餐巾.餐厅可以购买新的餐巾,每块餐巾的费用为 P PP 分:或者把旧餐巾送到快 ...
- 【zkw费用流】[网络流24题]餐巾计划问题
题目描述 一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,-,N).餐厅可以从三种途径获得餐巾. (1)购买新的餐巾,每块需p分: (2)把用过的餐巾送到快洗部,洗一块需m天,费用需f分(f ...
- 【Codevs1237&网络流24题餐巾计划】(费用流)
题意:一个餐厅在相继的 N 天里,每天需用的餐巾数不尽相同. 假设第 i 天需要 ri块餐巾(i=1,2,…,N).餐厅可以购买新的餐巾,每块餐巾的费用为 p 分: 或者把旧餐巾送到快洗部,洗一块需 ...
- Cogs 461. [网络流24题] 餐巾(费用流)
[网络流24题] 餐巾 ★★★ 输入文件:napkin.in 输出文件:napkin.out 简单对比 时间限制:5 s 内存限制:128 MB [问题描述] 一个餐厅在相继的N天里,第i天需要Ri块 ...
- [网络流24题]餐巾(cogs 461)
[问题描述] 一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,-,N).餐厅可以从三种途径获得餐巾. (1)购买新的餐巾,每块需p分: (2)把用过的餐巾送到快洗部,洗一块需m天,费用需f分 ...
- CGOS461 [网络流24题] 餐巾(最小费用最大流)
题目这么说的: 一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,…,N).餐厅可以从三种途径获得餐巾. 购买新的餐巾,每块需p分: 把用过的餐巾送到快洗部,洗一块需m天,费用需f分(f< ...
- COGS461. [网络流24题] 餐巾
[问题描述] 一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,…,N).餐厅可以从三种途径获得餐巾. (1)购买新的餐巾,每块需p分: (2)把用过的餐巾送到快洗部,洗一块需m天,费用需f分 ...
- 【COGS 461】[网络流24题] 餐巾 最小费用最大流
既然是最小费用最大流我们就用最大流来限制其一定能把每天跑满,那么把每个表示天的点向T连流量为其所需餐巾,费用为0的边,然后又与每天的餐巾对于买是无限制的因此从S向每个表示天的点连流量为INF,费用为一 ...
- LibreOJ #6008. 「网络流 24 题」餐巾计划 最小费用最大流 建图
#6008. 「网络流 24 题」餐巾计划 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 ...
- Libre 6008 「网络流 24 题」餐巾计划 (网络流,最小费用最大流)
Libre 6008 「网络流 24 题」餐巾计划 (网络流,最小费用最大流) Description 一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,-,N).餐厅可以从三种途径获得餐巾. ...
随机推荐
- Git配置和使用?Git你真的会用么?Git与SVN的主要区别
1.Git环境配置 在学习Git之前,首先要知道什么是版本控制 1.1 版本控制:版本迭代.新的版本!版本管理器 版本控制是开发过程中用于管理我们的文件.目录或工程内容的修改内容,查看修改历史记 ...
- 为什么你的static_assert不能按预期的工作?
static_assert是c++11添加的新语法,它可以使我们在编译期间检测一些断言条件是否为真,如果不满足条件将会产生一条编译错误信息. 使用静态断言可以提前暴露许多问题到编译阶段,极大的方便了我 ...
- 视觉享受,兼顾人文观感和几何特征的字体「GitHub 热点速览 v.22.46」
GitHub 上开源的字体不在少数,但是支持汉字以及其他非英文语言的字体少之又少,记得上一个字体还是 霞鹜文楷,本周 B 站知名设计 UP 主开源了的得意黑体在人文观感和几何特征之间找到了美的平衡. ...
- Python-OpenCV的安装及学习资料
Conda环境安装 OpenCV pip install opencv-python opencv-contrib-python -i https://mirrors.aliyun.com/pypi/ ...
- 【Devexpress】pivotGridControl设置不显示展开折叠按钮
只需要设置.效果看图二
- 快捷打开cmd管理员模式
win+s-搜索cmd 直接回车:普通用户模式的cmd CTRL+SHIFT+回车:管理员模式的cmd
- day29-JQuery02
JQuery02 4.jQuery选择器02 4.3过滤选择器 4.3.1基础过滤选择器 $("li:first") //第一个li $("li:last") ...
- 【笔面试真题】Flow++赋乐科技-面试-2022年1月25日
一.概括 涉及JVM的GC.三色标记 并发部分的锁 Java集合中的hashmap.list kafka中ISR相关 硬件相关-有无DMA 自定义类(代码) 缺陷:锁.list 二.JVM相关内容 1 ...
- Curve 块存储应用实践 -- iSCSI
Curve 是云原生计算基金会 (CNCF) Sandbox 项目,是网易数帆发起开源的高性能.易运维.云原生的分布式存储系统. 为了让大家更容易使用以及了解 Curve,我们期望接下来通过系列应用实 ...
- 基于 Spring Cloud 的微服务脚手架
基于 Spring Cloud 的微服务脚手架 作者: Grey 原文地址: 博客园:基于 Spring Cloud 的微服务脚手架 CSDN:基于 Spring Cloud 的微服务脚手架 本文主要 ...