zoukankan      html  css  js  c++  java
  • UVA-11613 Acme Corporation (最大费用最大流+拆点)

    题目大意:有一种商品X,其每每单位存放一个月的代价I固定。并且已知其每月的最大生产量、生产每单位的的代价、最大销售量和销售单价,还已知每个月生产的X能最多能存放的时间(以月为单位)。问只考虑前m个月,最多能获得多少利润。

    题目分析:增加源点s和汇点t,将每一个月视作一个节点。建立图模型如下:将每一个节点拆成两个,即将v拆成v和v1,从s向所有的v连一条弧,容量为该月最大生产量,费用为该月的单位生产代价;然后从所有的v1出发连一条弧向t,容量为该月最大销售量,费用为销售单价的相反数;最后,从v出发向所有它能存放到的月数u对应的u1连一条弧,容量为正无穷大,费用为I*(u-v)。对该模型求最小费用最大流,显然,这里对最小费用取相反数便的最大利润。

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<cmath>
    # include<string>
    # include<vector>
    # include<list>
    # include<set>
    # include<map>
    # include<queue>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    
    # define LL long long
    # define REP(i,s,n) for(int i=s;i<n;++i)
    # define CL(a,b) memset(a,b,sizeof(a))
    # define CLL(a,b,n) fill(a,a+n,b)
    
    const double inf=1e30;
    const int INF=1<<30;
    const int N=300;
    
    struct Edge
    {
        int fr,to;
        LL cap,flow,cost;
        Edge(int _fr,int _to,LL _cap,LL _flow,LL _cost):fr(_fr),to(_to),cap(_cap),flow(_flow),cost(_cost){}
    };
    vector<Edge>edges;
    vector<int>G[N];
    int p[N],inq[N],n,I;
    LL a[N],d[N];
    
    void init()
    {
        edges.clear();
        REP(i,0,n) G[i].clear();
    }
    
    void addEdge(int fr,int to,LL cap,LL cost)
    {
        edges.push_back(Edge(fr,to,cap,0,cost));
        edges.push_back(Edge(to,fr,0,0,-cost));
        int m=edges.size();
        G[fr].push_back(m-2);
        G[to].push_back(m-1);
    }
    
    bool BellmanFord(int s,int t,LL &flow,LL &cost)
    {
        CL(inq,0);
        CLL(d,INF,n);
        d[s]=0,inq[s]=1,p[s]=0,a[s]=INF;
    
        queue<int>q;
        q.push(s);
        while(!q.empty()){
            int u=q.front();
            q.pop();
            inq[u]=0;
            REP(i,0,G[u].size()){
                Edge &e=edges[G[u][i]];
                if(e.cap>e.flow&&d[e.to]>d[u]+e.cost){
                    d[e.to]=d[u]+e.cost;
                    p[e.to]=G[u][i];
                    a[e.to]=min(a[u],e.cap-e.flow);
                    if(!inq[e.to]){
                        q.push(e.to);
                        inq[e.to]=1;
                    }
                }
            }
        }
        if(d[t]>0) return false;
        flow+=(LL)a[t];
        cost+=(LL)d[t]*(LL)a[t];
        for(int u=t;u!=s;u=edges[p[u]].fr){
            edges[p[u]].flow+=a[t];
            edges[p[u]^1].flow-=a[t];
        }
        return true;
    }
    
    LL Mincost(int s,int t)
    {
        LL flow=0,cost=0;
        while(BellmanFord(s,t,flow,cost));
        return cost;
    }
    
    struct X
    {
        int m,n,p,s,E;
    };
    X x[105];
    
    int main()
    {
        int T,m,s,t,cas=0;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&m,&I);
            n=2*m+2;
            s=0,t=2*m+1;
            init();
            REP(i,1,m+1) scanf("%d%d%d%d%d",&x[i].m,&x[i].n,&x[i].p,&x[i].s,&x[i].E);
            REP(i,1,m+1){
                addEdge(0,2*i-1,x[i].n,x[i].m);
                addEdge(2*i,t,x[i].s,-x[i].p);
            }
            REP(i,1,m+1) REP(j,i,min(i+x[i].E,m)+1)
                addEdge(2*i-1,2*j,INF,I*(j-i));
            printf("Case %d: %lld
    ",++cas,-Mincost(s,t));
        }
        return 0;
    }
    

      

  • 相关阅读:
    多线程之同步代码块与同步函数
    图片上传客户端与服务端
    tcp上传学习二--文本文件上传
    javaScript编写9*9口诀
    tcp聊天
    udp聊天室--简易
    往sencha.cmd中恢复设计项时,不论是系统的还是应用的,恢复进去之后都应该一键发布到前端
    一个设计项上的按钮调另一个设计项的列表界面,同时加筛选条件
    点击【****】设计项上的某个按钮,直接调出另一个设计项的【编辑界面】
    前端向后端发送请求,后端返回的一个值的请求的ajax.get();方法
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/5046956.html
Copyright © 2011-2022 走看看