码迷,mamicode.com
首页 > 其他好文 > 详细

UVA-11613 Acme Corporation (最大费用最大流+拆点)

时间:2015-12-15 01:05:52      阅读:226      评论:0      收藏:0      [点我收藏+]

标签:

题目大意:有一种商品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\n",++cas,-Mincost(s,t));
    }
    return 0;
}

  

UVA-11613 Acme Corporation (最大费用最大流+拆点)

标签:

原文地址:http://www.cnblogs.com/20143605--pcx/p/5046956.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!