zoukankan      html  css  js  c++  java
  • 【费用流】P2517 [HAOI2010]订货

    P2517 [HAOI2010]订货

    思路:

    (为啥这题不用拆点而UVA11613 Acme Corporation需要?两道题有什么共同点和区别?)

    从这题可以窥见费用流问题的总体模型:有进有出,进出口在网络两端(超级源和超级汇),网络内部通过各种约束关系关联起来。

    本题中,就是每个月(i)进货,费用为(D_i),且没有限制进货数量故可以无限进货,所以是一条容量为INF且单位费用为(D_i)的边,故建边addf(s, i, INF, p)

    就是每个月(i)销售,销售没有费用,但有需求量的限制,超过需求量是卖不出去的,所以是一条容量为(U_i)(代码中为p)且单位费用为(0)的边,建边addf(i, t, p, 0)

    除第(n)个月外,每个月卖不完的货可以存储到仓库中,等到下个月再卖,仓库容量为(vol),单位存储费用为(cost),故除第(n)个月外每个月(i)向下一个月(i+1)连边,容量为(vol),费用为(cost),建边addf(i, i + 1, vol, cost)

    然后跑最小费用最大流即可。

    int cnt_e = 0, head[maxn], n, m;
    int s, t;
    LL dis[maxn], d[maxn];
    int pre[maxn];
    bool inq[maxn];
    LL maxflow, mincost;
    
    void addf(int u, int v, LL w, LL c) {
        //费用流建图
        e[++cnt_e].next = head[u]; e[cnt_e].from = u; e[cnt_e].to = v; e[cnt_e].w = w; e[cnt_e].cost = c; head[u] = cnt_e;
        e[++cnt_e].next = head[v]; e[cnt_e].from = v; e[cnt_e].to = u; e[cnt_e].w = 0; e[cnt_e].cost = -c; head[v] = cnt_e;
    }
    
    bool spfa() {
        queue<int> q;
        mem(dis, INF);
        mem(d, 0);
        mem(inq, 0);
        q.push(s); dis[s] = 0; inq[s] = 1;
        d[s] = INF;
        while (!q.empty()) {
            int u = q.front();
            inq[u] = 0; q.pop();
            for (int i = head[u]; i; i = e[i].next) {
                if (e[i].w <= 0) continue;
                int v = e[i].to;
                if (dis[u] + e[i].cost < dis[v]) {
                    dis[v] = dis[u] + e[i].cost;
                    //费用最短路
                    pre[v] = i;
                    d[v] = min(d[u], e[i].w);
                    //维护路径上的最小残量
                    if (!inq[v]) {
                        inq[v] = 1;
                        q.push(v);
                    }
                }
            }
        }
        if (!d[t]) return 0;
        return 1;
    }
    
    void MCMF() {
        while (spfa()) {
            for (int x = t; x != s; x = e[pre[x] ^ 1].to) {
                e[pre[x]].w -= d[t];
                e[pre[x] ^ 1].w += d[t];
            }
            maxflow += d[t];
            mincost += d[t] * dis[t];
            //流量乘上最小单位流量费用即总流量费用
        }
    }
    
    int main() {
        ios::sync_with_stdio(false);
        int cost, vol;
        cnt_e = 1;
        cin >> n >> cost >> vol;
        s = n + 1; t = n  + 2;
        for (int i = 1; i <= n; i++) {
            int p; cin >> p;
            addf(i, t, p, 0);
            //需求量为p,最多卖掉p,故容量p
            //卖出不需要花费,费用为0
        }
        for (int i = 1; i <= n; i++) {
            int p; cin >> p;
            addf(s, i, INF, p);
            //可以无限进货,故容量INF
            //进价为p,费用为p
        }
        //左点连右点,容量vol,费用为cost
        //在相邻的月间连,不是两两之间都连qwq
        for (int i = 1; i < n; i++) {
            addf(i, i + 1, vol, cost);
        }
        MCMF();
        cout << mincost;
        return 0;
    }
    
  • 相关阅读:
    四叶草社交平台——十天冲刺(7)
    四叶草社交平台——十天冲刺(6)
    多表查询
    单表 查询
    django模板的导入
    2019-3-1
    DJANGO 28
    路由
    Django项目的创建与介绍
    数据传输方式
  • 原文地址:https://www.cnblogs.com/streamazure/p/13909089.html
Copyright © 2011-2022 走看看