zoukankan      html  css  js  c++  java
  • [网络流24题]餐巾计划问题

    题目:洛谷P1251。

    题目大意:
    一个餐厅N天,每天需要ri块餐巾。每块餐巾需要p元,每天用过的餐巾变脏,不能直接用。现在有快洗店和慢洗店,快洗店洗餐巾需要m天,每块花费f元;慢洗店洗餐巾需要n天,每块餐巾s元(m < n,s<  f)。现要求最新的花费使满足每天所需。
    解题思路:
    最小费用最大流建模。
    把每天拆成白天和晚上(白天产生脏餐巾,晚上得到干净餐巾)。
    从S向每个白天连容量ri,费用0的边;从每个晚上向T连容量ri,费用0的边。代表每天所需的餐巾数。
    从第i天的白天向第i+m天的晚上连容量无穷,费用f的边。(快洗)
    从第i天的白天向第i+n天的晚上连容量无穷,费用s的边。(慢洗)
    从S向每天晚上连容量无穷,费用p的边,代表直接买干净的餐巾。
    从第i天晚上向第i+1天晚上连容量无穷,费用0的边,代表干净餐巾可以留到下一天。
    跑费用流即可。

    C++ Code:

    #include<bits/stdc++.h>
    using namespace std;
    #define T 7000
    #define N 7005
    #define LoveLive long long
    #define inf 0x3f3f3f3f
    int n,p,m,f,nn,s,h[2005];
    inline int readint(){
    	int c=getchar(),d=0;
    	for(;!isdigit(c);c=getchar());
    	for(;isdigit(c);c=getchar())
    	d=(d<<3)+(d<<1)+(c^'0');
    	return d;
    }
    struct Graph{
    	std::queue<int>q;
    	int head[N],cnt,pre_e[N],a[N];
    	LoveLive d[N];
    	bool vis[N];
    	struct edge{
    		int from,to,cap,cost,nxt;
    	}e[1000005];
    	inline void addedge(const int u,const int v,const int flow,const int cost){
    		e[++cnt]=(edge){u,v,flow,cost,head[u]};
    		head[u]=cnt;
    		e[++cnt]=(edge){v,u,0,-cost,head[v]};
    		head[v]=cnt;
    	}
    	Graph():cnt(1){
    		memset(head,-1,sizeof head);
    	}
    	bool bfs(LoveLive& flow,LoveLive& cost){
    		memset(d,0x3f,sizeof d);
    		memset(a,0x3f,sizeof a);
    		memset(vis,0,sizeof vis);
    		memset(pre_e,0,sizeof pre_e);
    		d[0]=0;
    		vis[0]=1;
    		q.push(0);
    		while(!q.empty()){
    			int u=q.front();q.pop();
    			vis[u]=0;
    			for(int i=head[u];~i;i=e[i].nxt)
    			if(e[i].cap&&d[e[i].to]>d[u]+e[i].cost){
    				d[e[i].to]=d[u]+e[i].cost;
    				a[e[i].to]=min(a[u],e[i].cap);
    				pre_e[e[i].to]=i;
    				if(!vis[e[i].to]){
    					vis[e[i].to]=1;
    					q.push(e[i].to);
    				}
    			}
    		}
    		if(d[T]>100000000000000000)return 0;
    		flow+=a[T];
    		cost+=d[T]*a[T];
    		for(int i=T;i;i=e[pre_e[i]].from){
    			e[pre_e[i]].cap-=a[T];
    			e[pre_e[i]^1].cap+=a[T];
    		}
    		return 1;
    	}
    	LoveLive ek(){
    		LoveLive flow=0,cost=0;
    		while(bfs(flow,cost));
    		return cost;
    	}
    }g;
    int main(){
    	n=readint();
    	for(int i=1;i<=n;++i)h[i]=readint();
    	p=readint(),m=readint(),f=readint(),nn=readint(),s=readint();
    	for(int i=1;i<=n;++i){
    		g.addedge(0,i,h[i],0);
    		g.addedge(i+n,T,h[i],0);
    		if(i+m<=n)g.addedge(i,i+n+m,inf,f);
    		if(i+nn<=n)g.addedge(i,i+n+nn,inf,s);
    		g.addedge(0,i+n,inf,p);
    		if(i!=n)g.addedge(i,i+1,inf,0);
    	}
    	cout<<g.ek()<<endl;
    	return 0;
    }
    
  • 相关阅读:
    POJ 2175 Evacuation Plan 费用流 负圈定理
    POJ 2983 Is the Information Reliable? 差分约束
    codeforces 420B Online Meeting
    POJ 3181 Dollar Dayz DP
    POJ Ant Counting DP
    POJ 1742 Coins DP 01背包
    中国儒学史
    产品思维30讲
    Java多线程编程核心技术
    编写高质量代码:改善Java程序的151个建议
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/9130400.html
Copyright © 2011-2022 走看看