洛谷P1251 餐巾计划问题 无汇源最小费用流

题目描述

一个餐厅在相继的 NN 天里,每天需用的餐巾数不尽相同。假设第 ii 天需要 r_iri​块餐巾( i=1,2,...,N)。餐厅可以购买新的餐巾,每块餐巾的费用为 pp 分;或者把旧餐巾送到快洗部,洗一块需 m 天,其费用为 f 分;或者送到慢洗部,洗一块需 nn 天(n>mn>m),其费用为 ss 分(s<fs<f)。

每天结束时,餐厅必须决定将多少块脏的餐巾送到快洗部,多少块餐巾送到慢洗部,以及多少块保存起来延期送洗。但是每天洗好的餐巾和购买的新餐巾数之和,要满足当天的需求量。

试设计一个算法为餐厅合理地安排好 NN 天中餐巾使用计划,使总的花费最小。编程找出一个最佳餐巾使用计划。

输入格式

由标准输入提供输入数据。文件第 1 行有 1 个正整数 NN,代表要安排餐巾使用计划的天数。

接下来的 NN 行是餐厅在相继的 NN 天里,每天需用的餐巾数。

最后一行包含5个正整数p,m,f,n,sp,m,f,n,s。pp 是每块新餐巾的费用; mm 是快洗部洗一块餐巾需用天数; ff 是快洗部洗一块餐巾需要的费用; nn 是慢洗部洗一块餐巾需用天数; ss 是慢洗部洗一块餐巾需要的费用。

输出格式

将餐厅在相继的 N 天里使用餐巾的最小总花费输出

输入输出样例

输入 #1复制

3
1 7 5 
11 2 2 3 1

输出 #1复制

134

说明/提示

N<=2000

ri<=10000000

p,f,s<=10000

时限4s

一道建图特别清新的一道题

注意要开long long

#include<bits/stdc++.h>
const int maxn = 1e5 + 10;
const int inf = 0x3f3f3f3f;
long long head[maxn];
long long vis[maxn];
long long dis[maxn];
long long flow[maxn];
long long pre[maxn];
long long last[maxn];
long long tot;
long long n, m, s, t;
using namespace std;
struct node{
	long long to;
	long long next;
	long long f;
	long long w;
	node() {}
	node(long long a, long long b, long long c, long long d) : to(a), next(b), f(c), w(d) {}
}edge[maxn * 10];
 
void edgeadd(long long a, long long b, long long c, long long d){
	edge[tot] = node(b, head[a], c, d);
	head[a] = tot++;
	edge[tot] = node(a, head[b], 0, -d);
	head[b] = tot++;
}
 
void init(){
	memset(head, -1, sizeof(head));
	tot = 0;
}
 
void spfainit(){
	memset(vis, 0, sizeof(vis));
	memset(dis, 0X3f3f3f3f, sizeof(dis));
	memset(flow, 0x3f3f3f3f, sizeof(flow));
}
 
bool spfa(){
	spfainit();
	queue<long long> q;
	q.push(s);
	pre[t] = -1;
	vis[s] = 1;
	dis[s] = 0;
	//flow[s] = 0;
	while(!q.empty()){
		long long nw = q.front();
		q.pop();
		vis[nw] = 0;
		for(long long i = head[nw]; i != -1; i = edge[i].next){
			long long y = edge[i].to;
			long long w = edge[i].w;
			long long f = edge[i].f;
			if(f && dis[y] > dis[nw] + w){
				dis[y] = dis[nw] + w;
				flow[y] = min(flow[nw], f);
				pre[y] = nw;
				last[y] = i;
				if(!vis[y]){
					q.push(y);
					vis[y] = 1;
				}
			}
		}
	}
	return pre[t] != -1;
}
 
void dinic(){
	long long maxflow = 0, minw = 0;
	while(spfa()){
	maxflow += flow[t];
	minw += flow[t] * dis[t];
		long long x = t;
		while(x != s){
			edge[last[x]].f -= flow[t];
			edge[(last[x] ^ 1)].f += flow[t];
			x = pre[x];
		}
	}
	cout << minw << endl;
}
int main(){
	ios::sync_with_stdio(false);
	cin >> n;
	init();
	s = 0;
	t = 2 * n + 1;
	for(long long i = 1; i <= n; i++){
		cin >> m;
		edgeadd(s, i, m, 0);
		edgeadd(i + n, t, m, 0);
	}
		long long a, b, c, d, e;
		cin >> a >> b >> c >> d >> e;
		for(long long i = 1; i <= n; i++){
			edgeadd(0, i + n, inf, a);
			if(i + 1 <= n) edgeadd(i, i + 1, inf, 0);
			if(i + b <= n) edgeadd(i, i + n + b, inf, c);
			if(i + d <= n) edgeadd(i, i + n + d, inf, e);
		}
	dinic();
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值