UVA - 11613 Acme Corporation(最小费用流)

来源:互联网 发布:淘宝9.9元天天特价包邮 编辑:程序博客网 时间:2024/05/04 16:48

题目大意:A公司生产一种元素,给出该元素在未来M个月中每个月的单位售价,最大生产量,生产成本,最大销售量和最大存储时间,和每月存储代价,问这家公司在M个月内所能赚大的最大利润

解题思路:这题建图还是比较简单的。主要说一下怎么跑出答案吧。我用的是MCMF,建边的时候,费用我用的是相反数,所以得到最小费用后要去相反数
MCMF的时候,用一个数组纪录了到达汇点时所花费的最小价值,因为取的是相反数,所以当价值为正时,就表示已经亏本了,所以可以退出了

#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#include <vector>using namespace std;#define N 1010#define ll long long#define abs(a)((a)>0?(a):(-(a)))#define INF 0x3f3f3f3f3f3f3f3fstruct Edge{    int from, to;    ll cap, flow ,cost;    Edge() {}    Edge(int from, int to, ll cap, ll flow, ll cost):from(from), to(to), cap(cap), flow(flow), cost(cost) {}};struct MCMF{    int n, m, source, sink;    vector<Edge> edges;    vector<int> G[N];    ll d[N], f[N];    int  p[N];    bool vis[N];    void init(int n) {        this->n = n;        for (int i = 0; i <= n; i++)            G[i].clear();        edges.clear();    }    void AddEdge(int from, int to, ll cap, ll cost) {        edges.push_back(Edge(from, to, cap, 0, cost));        edges.push_back(Edge(to, from, 0, 0, -cost));        m = edges.size();        G[from].push_back(m - 2);        G[to].push_back(m - 1);    }    bool BellmanFord(int s, int t, ll &flow, ll &cost) {        for (int i = 0; i <= n; i++)            d[i] = INF;        memset(vis, 0, sizeof(vis));        vis[s] = 1; d[s] = 0; f[s] = INF; p[s] = 0;        queue<int> Q;        Q.push(s);        while (!Q.empty()) {            int u = Q.front();            Q.pop();            vis[u] = 0;            for (int i = 0; i < G[u].size(); i++) {                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];                    f[e.to] = min(f[u], e.cap - e.flow);                    if (!vis[e.to]) {                        vis[e.to] = true;                        Q.push(e.to);                    }                }            }        }        if (d[t] > 0)            return false;        flow += f[t];        cost += d[t] * f[t];        int u = t;        while (u != s) {            edges[p[u]].flow += f[t];            edges[p[u] ^ 1].flow -= f[t];            u = edges[p[u]].from;        }        return true;    }    ll Mincost(int s, int t) {        ll flow = 0, cost = 0;        while (BellmanFord(s, t, flow, cost));        return cost;    }};MCMF mcmf;int n, m, source, sink, cas = 1;struct Node{        ll m, n, p, s, e;}node[N];void init() {    scanf("%d%d", &n, &m);    source = 0; sink = 2 * n + 1;    mcmf.init(sink);    for (int i = 1; i <= n; i++) {         scanf("%lld%lld%lld%lld%lld", &node[i].m, &node[i].n, &node[i].p, &node[i].s, &node[i].e);        mcmf.AddEdge(source, i, node[i].n, 0);        mcmf.AddEdge(i + n, sink, node[i].s, 0);    }    for (int i = 1; i <= n; i++) {        mcmf.AddEdge(i, i + n, INF, node[i].m - node[i].p);        for (int j = 1; j <= node[i].e && i + j <= n; j++)             mcmf.AddEdge(i, i + j + n, INF, m * j + node[i].m - node[i+j].p);    }    ll ans = mcmf.Mincost(source, sink);    printf("Case %d: %lld\n", cas++, abs(ans));}int main() {    int test;    scanf("%d", &test);    while (test--) {        init();    }    return 0;}
0 0
原创粉丝点击