BZOJ_2424_[HAOI2010]订货_最小费用最大流

BZOJ_2424_[HAOI2010]订货_最小费用最大流

Description

某公司估计市场在第i个月对某产品的需求量为Ui,已知在第i月该产品的订货单价为di,上个月月底未销完的单位产品要付存贮费用m,假定第一月月初的库存量为零,第n月月底的库存量也为零,问如何安排这n个月订购计划,才能使成本最低?每月月初订购,订购后产品立即到货,进库并供应市场,于当月被售掉则不必付存贮费。假设仓库容量为S。

Input

第1行:n, m, S (0<=n<=50, 0<=m<=10, 0<=S<=10000)
第2行:U1 , U2 , ... , Ui , ... , Un (0<=Ui<=10000)
第3行:d1 , d2 , ..., di , ... , dn (0<=di<=100)

Output

只有1行,一个整数,代表最低成本

Sample Input

3 1 1000
2 4 8
1 2 4

Sample Output

34

题目描述不清晰,其实可以在某天先卖一点在买的。
也就是说只要求剩下的不超过仓库容量即可。
于是S连第i天(inf,di),第i天连i+1天(inf,m),第i天连T(ui,0)。
跑最小费用最大流即可。
 
代码:
#include <cstdio>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 70
#define M 400050
#define S (n+1)
#define T (n+2)
#define inf 1<<30
int head[N],to[M],nxt[M],val[M],flow[M],cnt=1,n,m,C;
int U[N],D[N],dis[N],path[N],inq[N],Q[N],l,r;
void add(int u,int v,int f,int c) {
    to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; flow[cnt]=f; val[cnt]=c;
    to[++cnt]=u; nxt[cnt]=head[v]; head[v]=cnt; flow[cnt]=0; val[cnt]=-c;
}
bool spfa() {
    memset(dis,0x3f,sizeof(dis));
    memset(path,0,sizeof(path));
    l=r=0; dis[S]=0; Q[r++]=S;
    while(l!=r) {
        int x=Q[l++],i; inq[x]=0; if(l==T) l=0;
        for(i=head[x];i;i=nxt[i]) {
            if(dis[to[i]]>dis[x]+val[i]&&flow[i]) {
                dis[to[i]]=dis[x]+val[i];
                path[to[i]]=i^1;
                if(!inq[to[i]]) {
                    inq[to[i]]=1; Q[r++]=to[i]; if(r==T) r=0;
                }
            }
        }
    }
    return path[T];
}
void mcmf() {
    int ans=0,i;
    while(spfa()) {
        int nf=1<<30;
        for(i=T;i!=S;i=to[path[i]]) {
            nf=min(nf,flow[path[i]^1]);
        }
        for(i=T;i!=S;i=to[path[i]]) {
            ans+=nf*val[path[i]^1];
            flow[path[i]]+=nf;
            flow[path[i]^1]-=nf;
        }
    }
    printf("%d\n",ans);
}
int main() {
    scanf("%d%d%d",&n,&m,&C);
    int i;
    for(i=1;i<=n;i++) scanf("%d",&U[i]);
    for(i=1;i<=n;i++) scanf("%d",&D[i]);
    for(i=1;i<=n;i++) {
        add(S,i,inf,D[i]); add(i,T,U[i],0);
        if(i!=n) add(i,i+1,C,m);
    }
    mcmf();
}

 

posted @ 2018-06-03 09:07  fcwww  阅读(209)  评论(0编辑  收藏  举报