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. java学习之JSP

    0x00前言 JSP:全拼写:java Server pages:java 服务器端页面 可以理解为一个特殊的页面:可以定义html代码也可以定义java的代码 定义:JSP是简化Servlet编写的 ...

  2. Halocn双目相机标定

    [Halcon]Halcon双目标定 相机标定(4)---基于halcon的双目立体视觉标定 双目立体视觉:四(双目标定matlab,图像校正,图像匹配,计算视差,disparity详解,) 双目测距 ...

  3. C#使用正则表达式来验证是否是16进制字符串

    /// <summary> /// 判断是否为16进制字符串 /// </summary> /// <param name="hexString"&g ...

  4. 使用 Spring Cloud LoadBalancer 实现客户端负载均衡

    使用 Spring Cloud LoadBalancer 实现客户端负载均衡 作者:Grey 原文地址: 博客园:使用 Spring Cloud LoadBalancer 实现客户端负载均衡 CSDN ...

  5. 面试 考察网络请求HTTP相关知识(第六天!)

    01.HTTP 常⻅的状态码有哪些? 1xx 服务器收到请求 2xx 请求成功         ---   200 成功状态码 3xx 重定向            ---  301永久重定向,浏览器 ...

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

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

  7. Bugku md5 collision

    题目名字都叫md5碰撞,那就肯定和md5碰撞脱不了关系了 打开题目,首先让我们输入a 行吧,随意post一个a=1进去 结果提示flase 这里应该是有特殊值,我们找找看 查看源码,抓包 没找到 试试 ...

  8. Kubernetes(k8s)存储管理之数据卷volumes(四):持久卷Persistent Volume

    目录 一.系统环境 二.前言 三.持久卷(Persistent Volume) 3.1 持久卷(Persistent Volume)概览 3.2 持久卷和持久卷申领的生命周期 3.3 持久卷的类型 3 ...

  9. kernel 启动流程

    一.概述 之前学习了uboot的启动流程,现在接着学习uboot的启动流程,关于 kernel 的启动流程分析的大佬也是很多的,这里还是通过流程的图的方式进行记录,为了像我一样的新手,直观的了解 ke ...

  10. 静态文件配置 django连接MySQL django模型层初识 ORM基本语句

    目录 静态文件配置 1. 问题描述 2. 静态文件 3. 资源访问 form表单属性补充 action method 请求方法 get请求 post请求 views层 request对象 reques ...