【UVA11613 训练指南】生产销售规划 【费用流】

题意:

  Acme公司生产一种X元素,给出该元素在未来M个月中每个月的单位售价、最大产量、最大销售量,以及最大储存时间(过期报废不过可以储存任意多的量)。你的任务是计算出公司能够赚到的最大利润。

分析:

 把第i个月拆成i1和i2两个点,连一条s到i1的弧,容量为i月最大产量,费用为单位成本。连一条i2到t的弧,容量为最大销量,费用为单位售价的相反数。然后i1向i2连一条容量为INF费用为0的弧,代表当月销售。i1向其他j2连弧,容量为INF,费用为储藏代价。

 

另外,这个题属于流量不固定的最小费用流。也就是说,并不是一定要跑到最大流。用spfa寻找增广路的时候,当d[t]>0的时候就要停止增广。

  1     #include <cstdio>
  2     #include <algorithm>
  3     #include <cstring>
  4     #include <iostream>
  5     #include <queue>
  6     #include <vector>
  7 
  8     using namespace std;
  9     typedef long long LL;
 10     const int maxn=300+10;
 11     const int maxm=40000+10;
 12     const int INF=2147000000;
 13 
 14     struct MCMF{
 15         int head[maxn],to[maxm],Next[maxm],from[maxm],cost[maxm],flow[maxm],cap[maxm];
 16         int n,m,s,t,sz;
 17         int inq[maxn];
 18         int d[maxn];
 19         int p[maxn];
 20         int a[maxn];
 21 
 22         void init(int n){
 23             this->n=n;
 24             sz=-1;
 25             memset(head,-1,sizeof(head));
 26         }
 27         void AddEdge(int a,int b,int ca,int co){
 28             ++sz;
 29             to[sz]=b,from[sz]=a,Next[sz]=head[a],head[a]=sz;
 30             flow[sz]=0,cap[sz]=ca,cost[sz]=co;
 31             ++sz;
 32             to[sz]=a,from[sz]=b,Next[sz]=head[b],head[b]=sz;
 33             flow[sz]=ca,cap[sz]=ca,cost[sz]=-co;
 34         }
 35         bool BellmanFord(int s,int t,int &Flow,LL &Cost){
 36             for(int i=0;i<=n;i++)d[i]=INF;
 37             memset(inq,0,sizeof(inq));
 38             d[s]=0;inq[s]=1;p[s]=-1;a[s]=INF;
 39             queue<int>Q;
 40             Q.push(s);
 41             while(!Q.empty()){
 42                 int u=Q.front();Q.pop();
 43                 inq[u]=0;
 44                 for(int i=head[u];i!=-1;i=Next[i]){
 45                     int v=to[i];
 46                     if(cap[i]>flow[i]&&d[v]>d[u]+cost[i]){
 47                         d[v]=d[u]+cost[i];
 48                         p[v]=i;
 49                         a[v]=min(a[u],cap[i]-flow[i]);
 50                         if(!inq[v]){
 51                             Q.push(v);
 52                             inq[v]=1;
 53                         }
 54                     }
 55                 }
 56             }
 57             if(d[t]==INF||d[t]>0)return false;
 58             Flow+=a[t];
 59             Cost+=(LL)d[t]*(LL)a[t];
 60             int u=t;
 61 
 62             while(u!=s){
 63                 flow[p[u]]+=a[t];
 64                 flow[p[u]^1]-=a[t];
 65                 u=from[p[u]];
 66             }
 67             return true;
 68         }
 69 
 70         LL Mincost(int s,int t){
 71             int Flow=0;LL Cost=0;
 72             while(BellmanFord(s,t,Flow,Cost));
 73             return Cost;
 74         }
 75     }mcmf;
 76     const int maxM=150;
 77     int T,M,I,kase;
 78     int m[maxM],n[maxM],p[maxM],s[maxM],E[maxM];
 79 
 80     int main(){
 81         scanf("%d",&T);
 82        // freopen("out.txt","w",stdout);
 83         kase=0;
 84         for(int t=1;t<=T;t++){
 85             ++kase;
 86             scanf("%d%d",&M,&I);
 87             mcmf.init(2*M+2);
 88             mcmf.s=0;mcmf.t=2*M+1;
 89             for(int i=1;i<=M;i++){
 90                 scanf("%d%d%d%d%d",&m[i],&n[i],&p[i],&s[i],&E[i]);
 91                 mcmf.AddEdge(0,i,n[i],m[i]);
 92                 mcmf.AddEdge(i+M,2*M+1,s[i],-p[i]);
 93                 for(int j=0;j+i<=M&&j<=E[i];j++){
 94                     mcmf.AddEdge(i,i+j+M,INF,j*I);
 95                 }
 96             }
 97             LL ans=mcmf.Mincost(0,2*M+1);
 98             printf("Case %d: %lld\n",kase,-ans);
 99         }
100     return 0;
101     }
View Code

 

posted @ 2018-07-13 15:06  蒟蒻LQL  阅读(138)  评论(0编辑  收藏  举报