• [BZOJ 2424][HAOI2010]订货(费用流)


    Description

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

    Solution

    一道建图比较明显的费用流

    从s向每一天i连容量为INF费用为di的边

    从每一天i向t连容量为ui费用为0的边

    每一天向下一天连容量为S费用为m的边

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<queue>
    #define INF 0x3f3f3f3f
    using namespace std;
    int n,m,S,s,t;
    int head[505],cnt=0,a[505],dis[505],pre[505];
    bool inq[505];
    int read()
    {
        int x=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){
            if(c=='-')f=-1;c=getchar();
        }
        while(c>='0'&&c<='9'){
            x=x*10+c-'0';c=getchar();
        }
        return x*f;
    }
    struct Node
    {
        int next,from,to,cap,w;
    }Edges[5005];
    void addedge(int u,int v,int c,int w)
    {
        Edges[cnt].next=head[u];
        head[u]=cnt;
        Edges[cnt].from=u;
        Edges[cnt].to=v;
        Edges[cnt].cap=c;
        Edges[cnt++].w=w;
    }
    void insert(int u,int v,int c,int w)
    {
        addedge(u,v,c,w);
        addedge(v,u,0,-w);
    }
    queue<int>q;
    int MCMF()
    {
        int flow=0,cost=0;
        while(1)
        {
            memset(a,0,sizeof(a));
            memset(dis,0x3f,sizeof(dis));
            q.push(s);
            a[s]=INF,dis[s]=0,inq[s]=1,pre[s]=-1;
            while(!q.empty())
            {
                int u=q.front();
                q.pop(),inq[u]=0;
                for(int i=head[u];~i;i=Edges[i].next)
                {
                    int v=Edges[i].to;
                    if(dis[v]>dis[u]+Edges[i].w&&Edges[i].cap>0)
                    {
                        dis[v]=dis[u]+Edges[i].w;
                        a[v]=min(a[u],Edges[i].cap);
                        pre[v]=i;
                        if(!inq[v])
                        inq[v]=1,q.push(v);
                    }
                }
            }
            if(!a[t])break;
            flow+=a[t],cost+=a[t]*dis[t];
            int p=t;
            while(pre[p]!=-1)
            {
                Edges[pre[p]].cap-=a[t];
                Edges[pre[p]^1].cap+=a[t];
                p=Edges[pre[p]].from;
            }
        }
        return cost;
    }
    int main()
    {
        memset(head,-1,sizeof(head));
        n=read(),m=read(),S=read();
        s=0,t=n+1;
        for(int i=1;i<=n;i++)
        {
            int u=read();
            insert(i,t,u,0);
        }
        for(int i=1;i<=n;i++)
        {
            int d=read();
            insert(s,i,INF,d);
            if(i!=n)insert(i,i+1,S,m);
        }
        printf("%d
    ",MCMF());
        return 0;
    } 
  • 相关阅读:
    Nosql介绍
    linux系统安装mysql
    linux下装tomcat教程
    linux系统下安装jdk教程
    XML解析
    XML 可扩展标记语言
    Oracle——子查询
    数据库——Oracle(增删改查,单行函数,多行函数,多表查询)
    Ubuntu16.04Scrapy爬虫定时任务
    大数据——zookeeper分布式集群管理工具的学习与使用
  • 原文地址:https://www.cnblogs.com/Zars19/p/6870286.html
Copyright © 2020-2023  润新知