UVA 11613 Acme Corporation(不固定流量的最小费用流)

来源:互联网 发布:python metrics模块 编辑:程序博客网 时间:2024/05/22 00:21

题意好长。。。。变量好多。。。。

增加源点跟汇点。然后将每个月份看成一个点,然后拆成两个点u 跟 u+n。 

从s向每个u连一条<n[u], m[i]>的弧,表示最多生产量及价值。

从每个u+n向t连一条<s[i], -p[i]>的弧,表示最多销量及价值。

对于存放的情况 for(int j=0; j<=e[u] ; j++) if(u + j <= M) ,由u向u+j+M连一条<INF, I*j>的弧,表示存放所要花费的价值。

这题并不需要满足销量最大,也就是不固定流量的最小费用流,也就是说当s-t增广长度大于0的时候停止增广就行了。还有,稠密图ZKW效率不是太高。。。。

#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<queue>#define REP(i, n) for(int i=0; i<n; i++)#define CLR(a, b) memset(a, b, sizeof(a))#define FF(i, a, b) for(int i=a; i<b; i++)#define LL long longusing namespace std;const int maxn = 300;const int maxe = maxn*maxn/2;const int INF = 1e9;struct ZKW_flow{    int st, ed, ecnt, n;    int head[maxn], dis[maxn];    int cap[maxe], cost[maxe], to[maxe], next[maxe];    void init()    {        CLR(head, 0);        ecnt = 2;    }    void AddEdge(int u, int v, int cc, int ww)    {        cap[ecnt] = cc; cost[ecnt] = ww; to[ecnt] = v;        next[ecnt] = head[u]; head[u] = ecnt++;        cap[ecnt] = 0; cost[ecnt] = -ww; to[ecnt] = u;        next[ecnt] = head[v]; head[v] = ecnt++;    }    void spfa()    {        REP(i, n+1) dis[i] = INF;        priority_queue<pair<int, int> > q;        dis[st] = 0;        q.push(make_pair(0, st));        while(!q.empty())        {            int u = q.top().second, d = -q.top().first;            q.pop();            if(dis[u] != d) continue;            for(int p=head[u]; p; p=next[p])            {                int& v = to[p];                if(cap[p] && dis[v] > d+cost[p])                {                    dis[v] = d + cost[p];                    q.push(make_pair(-dis[v], v));                }            }        }        REP(i, n+1) dis[i] = dis[ed] - dis[i];    }    LL Mincost, Maxflow;    bool use[maxn];    int add_flow(int u, int flow)    {        if(u == ed)        {            if(dis[st] > 0) return flow;//不固定流量的最小费用流            Maxflow += flow;            Mincost += (LL)dis[st] * (LL)flow;            return flow;        }        use[u] = true;        int now = flow;        for(int p=head[u]; p; p=next[p])        {            int& v = to[p];            if(cap[p] && !use[v] && dis[u] == dis[v] + cost[p])            {                int tmp = add_flow(v, min(now, cap[p]));                cap[p] -= tmp;                cap[p^1] += tmp;                now -= tmp;                if(!now) break;            }        }        return flow - now;    }    bool modify_lable()    {        int d = INF;        REP(u, n+1) if(use[u])            for(int p=head[u]; p; p=next[p])            {                int& v = to[p];                if(cap[p] && !use[v])                    d = min(d, dis[v] + cost[p] - dis[u]);            }        if(d == INF) return false;        REP(i, n+1) if(use[i]) dis[i] += d;        return true;    }    LL MCMF(int ss, int tt, int nn)    {        st = ss; ed = tt; n = nn;        Mincost = Maxflow = 0;        spfa();        while(true)        {            while(true)            {                CLR(use, 0);                if(!add_flow(st, INF)) break;            }            if(!modify_lable()) break;        }        return Mincost;    }}solver;int T, M, I, st, ed;int m[maxn], n[maxn], p[maxn], s[maxn], e[maxn];int main(){    scanf("%d", &T);    FF(kase, 1, T+1)    {        scanf("%d%d", &M, &I);        solver.init();        st = 0, ed = M * 2 + 1;        FF(i, 1, M+1) scanf("%d%d%d%d%d", &m[i], &n[i], &p[i], &s[i], &e[i]);        FF(i, 1, M+1)        {            solver.AddEdge(st, i, n[i], m[i]);            solver.AddEdge(i+M, ed, s[i], -p[i]);            REP(j, e[i]+1) if(i + j <= M)                solver.AddEdge(i, i+j+M, n[i], I*j);            else break;        }        printf("Case %d: %lld\n", kase, -solver.MCMF(st, ed, ed));    }    return 0;}


原创粉丝点击