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的更多相关文章

  1. 网络流24题 餐巾计划(DCOJ8008)

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

  2. 【zkw费用流】[网络流24题]餐巾计划问题

    题目描述 一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,-,N).餐厅可以从三种途径获得餐巾. (1)购买新的餐巾,每块需p分: (2)把用过的餐巾送到快洗部,洗一块需m天,费用需f分(f ...

  3. 【Codevs1237&网络流24题餐巾计划】(费用流)

    题意:一个餐厅在相继的 N 天里,每天需用的餐巾数不尽相同. 假设第 i 天需要 ri块餐巾(i=1,2,…,N).餐厅可以购买新的餐巾,每块餐巾的费用为 p 分: 或者把旧餐巾送到快洗部,洗一块需 ...

  4. Cogs 461. [网络流24题] 餐巾(费用流)

    [网络流24题] 餐巾 ★★★ 输入文件:napkin.in 输出文件:napkin.out 简单对比 时间限制:5 s 内存限制:128 MB [问题描述] 一个餐厅在相继的N天里,第i天需要Ri块 ...

  5. [网络流24题]餐巾(cogs 461)

    [问题描述] 一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,-,N).餐厅可以从三种途径获得餐巾. (1)购买新的餐巾,每块需p分: (2)把用过的餐巾送到快洗部,洗一块需m天,费用需f分 ...

  6. CGOS461 [网络流24题] 餐巾(最小费用最大流)

    题目这么说的: 一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,…,N).餐厅可以从三种途径获得餐巾. 购买新的餐巾,每块需p分: 把用过的餐巾送到快洗部,洗一块需m天,费用需f分(f< ...

  7. COGS461. [网络流24题] 餐巾

    [问题描述] 一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,…,N).餐厅可以从三种途径获得餐巾. (1)购买新的餐巾,每块需p分: (2)把用过的餐巾送到快洗部,洗一块需m天,费用需f分 ...

  8. 【COGS 461】[网络流24题] 餐巾 最小费用最大流

    既然是最小费用最大流我们就用最大流来限制其一定能把每天跑满,那么把每个表示天的点向T连流量为其所需餐巾,费用为0的边,然后又与每天的餐巾对于买是无限制的因此从S向每个表示天的点连流量为INF,费用为一 ...

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

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

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

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

随机推荐

  1. Oracle数据库允许最大连接数

    1.查看当前的数据库连接数 SQL> select count(*) from v$process ; 2.数据库允许的最大连接数 SQL> select value from v$par ...

  2. 【云原生 · Kubernetes】apiserver高可用

    个人名片: 因为云计算成为了监控工程师‍ 个人博客:念舒_C.ying CSDN主页️:念舒_C.ying 7.1 高可用选型 ipvs+keepalived nginx+keepalived hap ...

  3. 谷歌、微软、Meta?谁才是 Python 最大的金主?

    你知道维护 Python 这个大规模的开源项目,每年需要多少资金吗? 答案是:约 200 万美元! PSF(Python 软件基金会)在 2022 年 6 月发布了 2021 的年度报告,其中披露了以 ...

  4. A-深度学习面试题

    目录 目录 一,滤波器与卷积核 二,卷积层和池化输出大小计算 2.1,CNN 中术语解释 2.2,卷积输出大小计算(简化型) 2.3,理解边界效应与填充 padding 参考资料 三,深度学习框架的张 ...

  5. OSError: dlopen() failed to load a library: cairo / cairo-2 / cairo-gobject-2 / cairo.so.2

    解决办法 下载 gtk3-runtime-3.24.29-2021-04-29-ts-win64.exe后安装. 记得勾选添加bin目录到环境变量: 这样就不会缺失dll了,当然可能需要重启IDE才能 ...

  6. 探讨Morest在RESTful API测试的行业实践

    摘要:在本文中,我们将重点探讨使用自动化智能化Morest测试技术在RESTful API测试的行业实践. 本文分享自华为云社区<[智能化测试专题]华为云API智能测试工具--Morest测试框 ...

  7. day33 过滤器filter & 监听器listener & 利用反射创建BaseServlet实现调用自定义业务方法

    Filter过滤器 Fileter可以实现: 1)客户端的请求访问servlet之前拦截这些请求,对用户请求进行预处理 2)对HttpServletResponse进行后处理: 注意 多个Filter ...

  8. [论文阅读] 颜色迁移-Correlated Color Space

    [论文阅读] 颜色迁移-Correlated Color Space 文章: Color transfer in correlated color space, [paper], [matlab co ...

  9. Mysql-delete语句

    ` 点击查看代码 删除2天之前的所有数据 delete From lkt_files_record where DATE(add_time) <= DATE(DATE_SUB(NOW(),INT ...

  10. python Modbus 进行通讯时抛出Modbus Error: Exception code = 2

    源码: import modbus_tk from modbus_tk import modbus_tcp import modbus_tk.defines as cst PORT = 'com1' ...