CGOS461 [网络流24题] 餐巾(最小费用最大流)
2016-04-07 18:48
357 查看
题目这么说的:
一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,…,N)。餐厅可以从三种途径获得餐巾。
购买新的餐巾,每块需p分;
把用过的餐巾送到快洗部,洗一块需m天,费用需f分(f<p)。如m=l时,第一天送到快洗部的餐巾第二天就可以使用了,送慢洗的情况也如此。
把餐巾送到慢洗部,洗一块需n天(n>m),费用需s分(s<f)。
在每天结束时,餐厅必须决定多少块用过的餐巾送到快洗部,多少块送慢洗部。在每天开始时,餐厅必须决定是否购买新餐巾及多少,使洗好的和新购的餐巾之和满足当天的需求量Ri,并使N天总的费用最小。
挺有趣的题,至少还需要稍微思考思考。。考虑用最小费用最大流。
首先显然要把各天作为点向汇点连容量为当天所需餐巾个数且费用为0的边,这样的最大流就满足各天供应的需求的条件;
然后对于购买餐巾,源点向各天连容量为INF费用p的边;
而最后还需要建洗餐巾重复利用餐巾的边,这么考虑:
对于第i天都会有Ri个餐巾可以重复利用,而第j天(j>=i+m)则可以得到快洗的第i天的餐巾,单位费用为f,慢洗的同理;
这样就清楚了:再新建n个顶点,源点向第i个新点连容量Ri费用0的边,第i个新点向第j天(j>=i+m)的点连容量INF费用f的边,第i个新点向第k天(k>=i+n)的点连容量INF费用s的边。
这样建完图跑最小费用最大流就OK了。
一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,…,N)。餐厅可以从三种途径获得餐巾。
购买新的餐巾,每块需p分;
把用过的餐巾送到快洗部,洗一块需m天,费用需f分(f<p)。如m=l时,第一天送到快洗部的餐巾第二天就可以使用了,送慢洗的情况也如此。
把餐巾送到慢洗部,洗一块需n天(n>m),费用需s分(s<f)。
在每天结束时,餐厅必须决定多少块用过的餐巾送到快洗部,多少块送慢洗部。在每天开始时,餐厅必须决定是否购买新餐巾及多少,使洗好的和新购的餐巾之和满足当天的需求量Ri,并使N天总的费用最小。
挺有趣的题,至少还需要稍微思考思考。。考虑用最小费用最大流。
首先显然要把各天作为点向汇点连容量为当天所需餐巾个数且费用为0的边,这样的最大流就满足各天供应的需求的条件;
然后对于购买餐巾,源点向各天连容量为INF费用p的边;
而最后还需要建洗餐巾重复利用餐巾的边,这么考虑:
对于第i天都会有Ri个餐巾可以重复利用,而第j天(j>=i+m)则可以得到快洗的第i天的餐巾,单位费用为f,慢洗的同理;
这样就清楚了:再新建n个顶点,源点向第i个新点连容量Ri费用0的边,第i个新点向第j天(j>=i+m)的点连容量INF费用f的边,第i个新点向第k天(k>=i+n)的点连容量INF费用s的边。
这样建完图跑最小费用最大流就OK了。
#include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespace std; #define INF (1<<30) #define MAXN 444 #define MAXM 444*888 struct Edge{ int u,v,cap,cost,next; }edge[MAXM]; int head[MAXN]; int NV,NE,vs,vt; void addEdge(int u,int v,int cap,int cost){ edge[NE].u=u; edge[NE].v=v; edge[NE].cap=cap; edge[NE].cost=cost; edge[NE].next=head[u]; head[u]=NE++; edge[NE].u=v; edge[NE].v=u; edge[NE].cap=0; edge[NE].cost=-cost; edge[NE].next=head[v]; head[v]=NE++; } bool vis[MAXN]; int d[MAXN],pre[MAXN]; bool SPFA(){ for(int i=0;i<NV;++i){ vis[i]=0; d[i]=INF; } vis[vs]=1; d[vs]=0; queue<int> que; que.push(vs); while(!que.empty()){ int u=que.front(); que.pop(); for(int i=head[u]; i!=-1; i=edge[i].next){ int v=edge[i].v; if(edge[i].cap && d[v]>d[u]+edge[i].cost){ d[v]=d[u]+edge[i].cost; pre[v]=i; if(!vis[v]){ vis[v]=1; que.push(v); } } } vis[u]=0; } return d[vt]!=INF; } int MCMF(){ int res=0; while(SPFA()){ int flow=INF,cost=0; for(int u=vt; u!=vs; u=edge[pre[u]].u){ flow=min(flow,edge[pre[u]].cap); } for(int u=vt; u!=vs; u=edge[pre[u]].u){ edge[pre[u]].cap-=flow; edge[pre[u]^1].cap+=flow; cost+=flow*edge[pre[u]].cost; } res+=cost; } return res; } int need[222]; int main(){ freopen("napkin.in","r",stdin); freopen("napkin.out","w",stdout); int n,p,a,b,x,y; scanf("%d",&n); for(int i=1; i<=n; ++i){ scanf("%d",need+i); } scanf("%d%d%d%d%d",&p,&a,&b,&x,&y); vs=0; vt=n*2+1; NV=vt+1; NE=0; memset(head,-1,sizeof(head)); for(int i=1; i<=n; ++i){ addEdge(vs,i+n,INF,p); addEdge(i+n,vt,need[i],0); addEdge(vs,i,need[i],0); for(int j=i+a; j<=n; ++j) addEdge(i,j+n,INF,b); for(int j=i+x; j<=n; ++j) addEdge(i,j+n,INF,y); } printf("%d",MCMF()); return 0; }
相关文章推荐
- android学习之网络连接2
- iOS开发网络篇—NSURLConnection基本使用
- http://coolshell.cn/articles/10910.html
- iOS 网络编程详解
- 396. [网络流24题]魔术球问题(简化版
- 利用HttpListener创建简单的HTTP服务
- 【codevs 2306】【bzoj 1877】[SDOI 2009]晨跑(费用流)
- iOS ASIHttpRequest 和 AFNetWorking 实时监测下载进度
- javaweb学习总结(四)——Http协议
- Linux网络编程入门 (转载)
- HTTP 1.1与HTTP 1.0的比较
- https authorization basic
- Linux网络编程必看书籍推荐
- HttpClient的超时用法小记
- 【bzoj 1458】士兵占领(最大流)
- 关于Xutils网络请求重试的问题
- TCP/NIO示例代码
- struts.xml不在默认位置,导致出现HTTP Status 404 - There is no Action mapped for namespace [/] and action name [
- 简单说说TCP(3) --- 断开连接四次握手
- Ngnix安装error: the HTTP rewrite module requires the PCRE library.