[网络流24题] 洛谷P1251 餐巾计划问题 费用流

一个餐厅在 n ≤ 2 e 3 n\leq2e3 n2e3的天内,每天都需要一些餐巾,第 i i i天需要 r i r_i ri的餐巾的数量,每天餐厅都可以花 p p p买一个新的餐巾。另外每天都可以把若干个餐巾送到快洗店或者慢洗店,快洗店是需要花 f f f块,洗 m m m天。慢洗店需要花 s s s块,洗 n n n天,也可以把餐巾保留到下一天
对建图能力要求比较高的费用流,好题。每一天都拆成两个点,分别代表白天和晚上,白天是处理干净的餐巾,而晚上是处理被用完的餐巾。
源点向每个白天连无限流量 f f f权值,代表我可以任意购买新的餐巾。
每个白天向汇点连 c i c_i ci流量 0 0 0权值,表示我最终需要的是 c i c_i ci条餐巾。
源点向每个晚上连 c i c_i ci流量 0 0 0权值,表示我要分配的是 c i c_i ci条餐巾。
每个晚上向下一个晚上连无限流量 0 0 0权值,表示我可以延期送洗。
每个晚上向下 m m m个白天连无限流量 f f f权值,表示快洗。
每个晚上向下 n n n个白天连无限流量 s s s权值,表示慢洗。
跑最小费用流为答案。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
namespace MCMF {
	const int N=4e3+7,M=1e5+7;
	int tot=-1,n,S,T; 
	int front[N],pre[N],lst[N];
	ll flow[N],dis[N];
	bool inq[N];
	struct edge{ int v,nxt;ll c,w; }e[2*M];
	void init() {
		tot=-1;
		for(int i=1;i<=n;i++) front[i]=-1;
	}
	void add(int u,int v,ll c,ll w) {
		e[++tot].v=v,e[tot].w=w,e[tot].c=c,e[tot].nxt=front[u],front[u]=tot;
		e[++tot].v=u,e[tot].w=-w,e[tot].c=0,e[tot].nxt=front[v],front[v]=tot;
	}
	void reset() {
		pre[T]=-1;
		for(int i=1;i<=n;i++) dis[i]=flow[i]=1e15;
		for(int i=1;i<=n;i++) inq[i]=0;
	}
	bool spfa() {
		reset();
		queue<int> q;
		q.push(S);
		inq[S]=1;dis[S]=0;
		while(!q.empty()) {
			int u=q.front();
			q.pop();
			inq[u]=0;
			for(int i=front[u];i!=-1;i=e[i].nxt) {
				int v=e[i].v;
				if(e[i].c>0) {
					if(dis[v]>dis[u]+e[i].w) {
						dis[v]=dis[u]+e[i].w;
						flow[v]=min(flow[u],e[i].c);
						pre[v]=u,lst[v]=i;
						if(!inq[v]) {
							inq[v]=1;
							q.push(v);
						}
					}
				}
			}
		}
		return pre[T]!=-1?1:0; 
	}
	pair<ll,ll> solve() {
		ll maxflow=0,mincost=0;
		while(spfa()) {
			int cur=T;
			maxflow+=flow[T];
			mincost+=flow[T]*dis[T];
			while(cur!=S) {
				e[lst[cur]].c-=flow[T];
				e[lst[cur]^1].c+=flow[T];
				cur=pre[cur];
			}
		}
		return make_pair(maxflow,mincost);
	} 
}
const int N=2e3+7;
int c[N];  
int main() {
	int N,p,m,f,n,s; 
	scanf("%d",&N);
	for(int i=1;i<=N;i++)
		scanf("%d",&c[i]);
	scanf("%d%d%d%d%d",&p,&m,&f,&n,&s);
	MCMF::n=2*N+2;
	int S=2*N+1;
	int T=2*N+2;
	MCMF::S=S;
	MCMF::T=T;
	MCMF::init(); 
	for(int i=N+1;i<=2*N;i++)
		MCMF::add(S,i,1e15,p);
	for(int i=N+1;i<=2*N;i++)
		MCMF::add(i,T,c[i-N],0);
	for(int i=1;i<=N;i++)
		MCMF::add(S,i,c[i],0);
	for(int i=1;i+1<=N;i++) 
		MCMF::add(i,i+1,1e15,0); 
	for(int i=1;i+m<=N;i++)
		MCMF::add(i,i+N+m,1e15,f);
	for(int i=1;i+n<=N;i++)
		MCMF::add(i,i+N+n,1e15,s);
	ll ans=MCMF::solve().second;
	printf("%lld\n",ans);  
	return 0;
}
Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值