Libre 6008 「网络流 24 题」餐巾计划 (网络流,最小费用最大流)
Libre 6008 「网络流 24 题」餐巾计划 (网络流,最小费用最大流)
Description
一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,…,N)。餐厅可以从三种途径获得餐巾。
(1)购买新的餐巾,每块需p分;
(2)把用过的餐巾送到快洗部,洗一块需m天,费用需f分(f<p)。如m=l时,第一天送到快洗部的餐巾第二天就可以使用了,送慢洗的情况也如此。
(3)把餐巾送到慢洗部,洗一块需n天(n>m),费用需s分(s<f)。
在每天结束时,餐厅必须决定多少块用过的餐巾送到快洗部,多少块送慢洗部。在每天开始时,餐厅必须决定是否购买新餐巾及多少,使洗好的和新购的餐巾之和满足当天的需求量Ri,并使N天总的费用最小。
Input
共 n+1 行:
第1行为总天教和每块餐巾的新购费用p,快洗所需天数d1,快洗所需费用c1,慢洗所需天数d2,慢洗所需费用c2;
下n行为每天所需的餐巾块数;
Output
一行,最小的费用
Sample Input
3 10 2 3 3 2
5
6
7
Sample Output
145
Http
Libre:https://loj.ac/problem/6008
Source
网络流,最小费用最大流
解决思路
题目还算好理解,但是建图需要考虑一些东西。
餐巾不管在那一天洗价格都是一样的,所以没有必要提前把旧餐巾洗成新餐巾让后放在那里不用。
首先对于每一天i,我们将其拆成两个点i和i+n,我们把前面一个称为旧餐巾,后面一个称为新餐巾。另建立源点0和汇点n*2+1。
需要连接的边有:
1 源点到旧餐巾,容量为r[i](就是第i天的餐巾需求啦),代价为0,这条表表示这一天有r[i]条新的旧餐巾产生
2 源点到新餐巾,容量为无穷大,代价为新购餐巾的费用。这条边的意思就是新购餐巾
3 新餐巾到汇点,容量为R[i],代价为0。这条边使用来限制第i天只能花掉r[i]条餐巾,也代表着强制让剩余的餐巾向后流,即不让多余的餐巾提前洗掉
4 从第i天的旧餐巾到第i+1天的旧餐巾,容量为无穷大,代价为0。这条边代表的是延时送洗,即把餐巾送到后面几天去
5 从第i天的旧餐巾到第i+d1(即快洗所需时间)天的新餐巾,容量为无穷大,代价为快洗所需代价。这条边代表送到快洗部快洗
6 从第i天的旧餐巾到第i+d2(即慢洗所需时间)天的新餐巾,容量为无穷大,代价为慢洗所需代价。这条边代表送到慢洗部慢洗
然后跑一边spfa最小费用最大流即可。
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxN=3100;
const int maxM=maxN*maxN*2;
const int inf=2147483647;
class Edge
{
public:
	int u,v,cost,flow;
};
int n,P,d1,c1,d2,c2;
int cnt=-1;
int Head[maxN];
int Next[maxM];
Edge E[maxM];
int Dist[maxN];
int path[maxN];
int Q[maxN*100];
bool inqueue[maxN];
int Flow[maxN];
void Add_Edge(int u,int v,int cost,int flow);
bool spfa();
int main()
{
	memset(Head,-1,sizeof(Head));
	scanf("%d%d%d%d%d%d",&n,&P,&d1,&c1,&d2,&c2);
	for (int i=1;i<=n;i++)
	{
		int r;
		scanf("%d",&r);
		Add_Edge(0,i,0,r);//源点到旧餐巾
		Add_Edge(0,i+n,P,inf);//从源点到新餐巾,即新购买餐巾
		Add_Edge(i+n,n*2+1,0,r);//从新餐巾到汇点,表示要用掉这么多餐巾
		if (i+1<=n)
			Add_Edge(i,i+1,0,inf);//延时送洗
		if (i+d1<=n)
			Add_Edge(i,i+d1+n,c1,inf);//送到快洗部
		if (i+d2<=n)
			Add_Edge(i,i+d2+n,c2,inf);//送到慢洗部
	}
	int Ans=0;
	while (spfa())
	{
		int now=n*2+1;
		int p=path[now];
		while (now!=0)
		{
			E[p].flow-=Flow[n*2+1];
			E[p^1].flow+=Flow[n*2+1];
			now=E[p].u;
			p=path[now];
		}
		Ans+=Flow[n*2+1]*Dist[n*2+1];
	}
	cout<<Ans<<endl;
	return 0;
}
void Add_Edge(int u,int v,int cost,int flow)
{
	cnt++;
	Next[cnt]=Head[u];
	Head[u]=cnt;
	E[cnt].u=u;
	E[cnt].v=v;
	E[cnt].cost=cost;
	E[cnt].flow=flow;
	cnt++;
	Next[cnt]=Head[v];
	Head[v]=cnt;
	E[cnt].u=v;
	E[cnt].v=u;
	E[cnt].cost=-cost;
	E[cnt].flow=0;
}
bool spfa()
{
	memset(Dist,-1,sizeof(Dist));
	memset(inqueue,0,sizeof(inqueue));
	int h=1,t=0;
	Q[1]=0;
	Dist[0]=0;
	inqueue[0]=1;
	Flow[0]=inf;
	do
	{
		t++;
		int u=Q[t];
		inqueue[u]=0;
		for (int i=Head[u];i!=-1;i=Next[i])
		{
			int v=E[i].v;
			if ((E[i].flow>0)&&((E[i].cost+Dist[u]<Dist[v])||(Dist[v]==-1)))
			{
				Dist[v]=Dist[u]+E[i].cost;
				path[v]=i;
				Flow[v]=min(Flow[u],E[i].flow);
				if (inqueue[v]==0)
				{
					h++;
					Q[h]=v;
					inqueue[v]=1;
				}
			}
		}
	}
	while (h!=t);
	if (Dist[n*2+1]==-1)
		return 0;
	return 1;
}
												
											Libre 6008 「网络流 24 题」餐巾计划 (网络流,最小费用最大流)的更多相关文章
- LibreOJ #6008. 「网络流 24 题」餐巾计划 最小费用最大流 建图
		
#6008. 「网络流 24 题」餐巾计划 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 ...
 - 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)\) ...
 - LibreOJ #6008. 「网络流 24 题」餐巾计划
		
这道题其实我在刚学 OI 的时候就在一本通上看见过,还记得上面写着"新餐巾一次性买完"之类的话.当时还很稚嫩(现在也是),想了好久,根本想不出来. 学了网络流之后发现这道题的图也是 ...
 - 【刷题】LOJ 6008 「网络流 24 题」餐巾计划
		
题目描述 一个餐厅在相继的 \(n\) 天里,每天需用的餐巾数不尽相同.假设第 \(i\) 天需要 \(r_i\) 块餐巾.餐厅可以购买新的餐巾,每块餐巾的费用为 \(P\) 分:或者把旧餐巾送到快洗 ...
 - Libre 6012 「网络流 24 题」分配问题  (网络流,费用流)
		
Libre 6012 「网络流 24 题」分配问题 (网络流,费用流) Description 有n件工作要分配给n个人做.第i个人做第j件工作产生的效益为\(c_{ij}\).试设计一个将n件工作分 ...
 - Libre 6011 「网络流 24 题」运输问题  (网络流,最小费用最大流)
		
Libre 6011 「网络流 24 题」运输问题 (网络流,最小费用最大流) Description W 公司有m个仓库和n个零售商店.第i个仓库有\(a_i\)个单位的货物:第j个零售商店需要\( ...
 - LibreOJ #6007. 「网络流 24 题」方格取数 最小割 最大点权独立集 最大流
		
#6007. 「网络流 24 题」方格取数 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 ...
 - LibreOJ 6004. 「网络流 24 题」圆桌聚餐 网络流版子题
		
#6004. 「网络流 24 题」圆桌聚餐 内存限制:256 MiB时间限制:5000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统计讨论测试数 ...
 
随机推荐
- 《网络对抗》Exp4 恶意代码分析
			
20155336<网络对抗>Exp4 恶意代码分析 问题回答 实验后回答问题 (1)如果在工作中怀疑一台主机上有恶意代码,但只是猜想,所有想监控下系统一天天的到底在干些什么.请设计下你想监 ...
 - STM32-M0中断优先级介绍
			
先解释中断优先级,后面讲代码的实现. 差异:M0的中断优先级相比于M4,没有用到分组,且只用到了2个bit位(即0~3)来设置,数值越小,优先级越高:同等优先级,根据终端号的大小来决定谁先执行. 根据 ...
 - python装饰器 练习
			
用类作为装饰器 练习一 最初代码 class bol(object): def __init__(self, func): self.func = func def __call__(self): r ...
 - libgdx学习记录24——九宫格NinePatch
			
NinePatch用于图片纹理拉伸显示.当图片拉伸时,4个角不会拉伸,而只有中间的部分会拉伸,适合做圆角矩形类的Button. 简单示例: package com.fxb.newtest; impor ...
 - VMware Tools安装和卸载
			
1.卸载 a.查找 vmware-uninstall-tools.pl 路径:sudo find / -name 'vmware-uninstall-tools.pl' b.切换到 vmware-un ...
 - Docker原理探究
			
问题思考:-------------------------------------Docker浅显原理理解-------------------------------------P1. ubunt ...
 - Vim操作指南
			
vim具有6种基本模式和5种派生模式. 基本模式 普通模式 插入模式 可视模式 选择模式 命令行模式 Ex模式 派生模式 操作符等待模式 插入普通模式 插入可视模式 插入选择模式 替换模式 1.移动光 ...
 - No.1110_第十一次团队会议
			
今天项目进展很多,第一轮迭代基本已经完成了,但是产品还没有发布,主要是因为大家还是太困了,所以再等一等明天再发布吧. 现在队员们急需补觉,因为最近实在是太辛苦了,很多人都没有休息好.现在已经基本完成了 ...
 - 关于github的使用心得
			
https://github.com/JavaLizheng/test git常用命令: git config :配置git git add:更新working directory中的文件至stagi ...
 - 人生第一次JAVA编程,电梯(并不算完成版),以及IDEA里使用git
			
首先先说说Intellij IDEA与git的互联,首先在任意(我是在coding)gitlab里新建一个工程. 然后新建一个工程记得注明url和地址.名称等 如果无法创建,则需要指定git地址 创建 ...