Bashu2445 -- 网络流24题-10餐巾问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Bashu2445 -- 网络流24题-10餐巾问题相关的知识,希望对你有一定的参考价值。
2445 -- 【网络流24题-10】餐巾问题
Description
一个餐厅在相继的n天里,每天需要用的餐巾数不尽相同。假设第i天需要ri块餐巾(i=1,2,…,n)。餐厅可以购买新的餐巾,每块餐巾的费用为p分;也可以把旧餐巾送到快洗部,洗一块需m天,其费用为f分;也可以把旧餐巾送到慢洗部,洗一块需要t天(t>m),其费用为s < f分。每天结束时,餐厅必须决定多少块脏的餐巾送到快洗部、多少块送到慢洗部以及多少块保存起来延期送洗。但是洗好的餐巾和购买的新餐巾之和,要满足第i天的需求量,并使总的花费最小。
Input
输入文件的第一行6个正整数n,p,m,f,t,s。n是需要安排餐巾使用计划的天数;p是每块新餐巾的费用;m是快洗部洗一块餐巾需用天数;f是快洗部洗一块餐巾需要的费用;t是慢洗部洗一块餐巾需用天数;s是慢洗部洗一块餐巾需要的费用。接下来的n行是餐厅在相继的n天里,每天需用的餐巾数。
【规模】:1≤f,t,s≤60,1≤n≤1000)
【规模】:1≤f,t,s≤60,1≤n≤1000)
Output
文件输出只有一行为在这n天里餐厅需要使用餐巾的最小总花费。
Sample Input
3 10 2 3 3 2
5
6
7
Sample Output
145
【建模分析】
这个问题的主要约束条件是每天的餐巾够用,而餐巾的来源可能是最新购买,也可能是前几天送洗,今天刚刚洗好的餐巾。每天用完的餐巾可以选择送到快洗部或慢洗部,或者留到下一天再处理。
经过分析可以把每天要用的和用完的分离开处理,建模后就是二分图。二分图X集合中顶点Xi表示第i天用完的餐巾,其数量为ri,所以从S向Xi连接容量为ri的边作为限制。Y集合中每个点Yi则是第i天需要的餐巾,数量为ri,与T连接的边容量作为限制。每天用完的餐巾可以选择留到下一天(Xi->Xi+1),不需要花费,送到快洗部(Xi->Yi+m),费用为f,送到慢洗部(Xi->Yi+n),费用为s。每天需要的餐巾除了刚刚洗好的餐巾,还可能是新购买的(S->Yi),费用为p。
这个问题的主要约束条件是每天的餐巾够用,而餐巾的来源可能是最新购买,也可能是前几天送洗,今天刚刚洗好的餐巾。每天用完的餐巾可以选择送到快洗部或慢洗部,或者留到下一天再处理。
经过分析可以把每天要用的和用完的分离开处理,建模后就是二分图。二分图X集合中顶点Xi表示第i天用完的餐巾,其数量为ri,所以从S向Xi连接容量为ri的边作为限制。Y集合中每个点Yi则是第i天需要的餐巾,数量为ri,与T连接的边容量作为限制。每天用完的餐巾可以选择留到下一天(Xi->Xi+1),不需要花费,送到快洗部(Xi->Yi+m),费用为f,送到慢洗部(Xi->Yi+n),费用为s。每天需要的餐巾除了刚刚洗好的餐巾,还可能是新购买的(S->Yi),费用为p。
【建模方法】
把每天分为二分图两个集合中的顶点Xi,Yi,建立附加源S汇T。
1、从S向每个Xi连一条容量为ri,费用为0的有向边。
2、从每个Yi向T连一条容量为ri,费用为0的有向边。
3、从S向每个Yi连一条容量为无穷大,费用为p的有向边。
4、从每个Xi向Xi+1(i+1<=N)连一条容量为无穷大,费用为0的有向边。
5、从每个Xi向Yi+m(i+m<=N)连一条容量为无穷大,费用为f的有向边。
6、从每个Xi向Yi+n(i+n<=N)连一条容量为无穷大,费用为s的有向边。
求网络最小费用最大流,费用流值就是要求的最小总花费。
把每天分为二分图两个集合中的顶点Xi,Yi,建立附加源S汇T。
1、从S向每个Xi连一条容量为ri,费用为0的有向边。
2、从每个Yi向T连一条容量为ri,费用为0的有向边。
3、从S向每个Yi连一条容量为无穷大,费用为p的有向边。
4、从每个Xi向Xi+1(i+1<=N)连一条容量为无穷大,费用为0的有向边。
5、从每个Xi向Yi+m(i+m<=N)连一条容量为无穷大,费用为f的有向边。
6、从每个Xi向Yi+n(i+n<=N)连一条容量为无穷大,费用为s的有向边。
求网络最小费用最大流,费用流值就是要求的最小总花费。
贴代码~
#include<cstdio> #include<cmath> #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<queue> using namespace std; const int maxn=2100,maxm=110000,inf=0x7fffffff; int n,m,p,f,ss,tt,a,b,s,t,mincost,tot=1,head[maxn],d[maxn],from[maxm*2]; queue<int> q; bool v[maxn]; struct node{ int from,go,v,c,next; }e[maxm*2]; inline int read(){ int x=0;char ch=getchar(); while (ch<‘0‘ || ch>‘9‘) ch=getchar(); while (ch>=‘0‘ && ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x; } inline void addedge(int x,int y,int v,int c){ e[++tot]=(node){x,y,v,c,head[x]};head[x]=tot; e[++tot]=(node){y,x,0,-c,head[y]};head[y]=tot; } bool spfa(){ for (int i=s;i<=t;i++) v[i]=0,d[i]=inf; q.push(s);d[s]=0;v[s]=1; while (!q.empty()){ int x=q.front();q.pop();v[x]=0; for (int i=head[x],y;i;i=e[i].next){ if (e[i].v && d[x]+e[i].c<d[y=e[i].go]){ d[y]=d[x]+e[i].c;from[y]=i; if (!v[y]) v[y]=1,q.push(y); } } } return d[t]!=inf; } void mcf(){ mincost=0; while(spfa()){ int tmp=inf; for (int i=from[t];i;i=from[e[i].from]) tmp=min(tmp,e[i].v); mincost+=tmp*d[t]; for (int i=from[t];i;i=from[e[i].from]) e[i].v-=tmp,e[i^1].v+=tmp; } } int main(){ scanf("%d%d%d%d%d%d",&n,&p,&m,&f,&tt,&ss); s=0;t=n+n+1; for (int i=1;i<=n;i++){ a=read(); addedge(s,i,a,0); addedge(n+i,t,a,0); addedge(s,n+i,inf,p); if (i<n) addedge(i,i+1,inf,0); if (i+m<=n) addedge(i,n+m+i,inf,f); if (i+tt<=n) addedge(i,n+i+tt,inf,ss); } mcf(); printf("%d\n",mincost); }
以上是关于Bashu2445 -- 网络流24题-10餐巾问题的主要内容,如果未能解决你的问题,请参考以下文章