#网络流,最小费用最大流,Edmons-Karp#codevs 1863 洛谷 2517 ssl 2401 订货

题目

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


分析

最小费用最大流,过程很简单,建图。
这里写图片描述
That’s all.Edmons-Karp


代码

#include <cstdio>
#include <queue>
using namespace std;
struct node{int y,next,w,c;}e[501];
int k=1,ls[61],dis[61],n,s,t,m,store,pre[61],ans,x; bool v[61];
void add(int x,int y,int w,int c){
    e[++k].y=y; e[k].w=w; e[k].c=c; e[k].next=ls[x]; ls[x]=k;
    e[++k].y=x; e[k].w=0; e[k].c=-c;e[k].next=ls[y]; ls[y]=k;
}
bool spfa(){
    queue<int>q; 
    for (int i=1;i<=n+2;i++) v[i]=0;
    for (int i=1;i<=n+2;i++) dis[i]=707406378;
    dis[s]=0; v[s]=1; q.push(s);
    while (q.size()){
        int u=q.front(); q.pop();
        for (int i=ls[u];i;i=e[i].next)
        if (e[i].w>0&&dis[u]+e[i].c<dis[e[i].y]){
            dis[e[i].y]=dis[u]+e[i].c; pre[e[i].y]=i;
            if (!v[e[i].y]) v[e[i].y]=1,q.push(e[i].y);
        }
        v[u]=0;
    }
    if (dis[t]<707406378) return 1; else return 0;
}
void update(){
    m=2147483647; int x=t;
    while (x!=s) m=min(m,e[pre[x]].w),x=e[pre[x]^1].y;
    ans+=dis[t]*m; x=t; 
    while (x!=s) e[pre[x]].w-=m,e[pre[x]^1].w+=m,x=e[pre[x]^1].y;
}
int main(){
    scanf("%d%d%d",&n,&m,&store); s=n+1; t=n+2;
    for (int i=1;i<=n;i++) scanf("%d",&x),add(i,t,x,0);
    for (int i=1;i<=n;i++) scanf("%d",&x),add(s,i,1e6,x);
    for (int i=1;i<n;i++) add(i,i+1,store,m);
    while (spfa()) update();
    return !printf("%d",ans);
}

猜你喜欢

转载自blog.csdn.net/sugar_free_mint/article/details/80774388
今日推荐