zoukankan      html  css  js  c++  java
  • 【费用流+正负费用处理】UVA11613 Acme Corporation

    UVA11613 Acme Corporation

    思路

    对于第(i)个月,货物来源有:当月生产(从源点流入),以及之前的月份流入。因为有保质期,这意味着第(i-1)个月留下来的货物里保质期会各不相同,可能其中一部分是第(i)个月就过期无法卖出的,这一部分货物显然不能流入第(i)个月。

    如何连边才能体现“在保质期内卖出”?这就需要将一个月份的流入和流出分别处理,也就是拆成入点(i)和出点(i+n)。这样,假设在第(i)个月生产的货物保质期为(keep[i]),那么它就可以在第(i)(i+1)(i+2),...,(i+keep[i])月卖出,具体建边就是(i→i+n)(i→i+1+n)(i→i+2+n),...,(i→i+keep[i]+n)。这样,网络内部建边就完成了。

    由于费用有正有负(生产成本和盈利),比板子多设一个条件if(dis[t]≥0) return 0; ,即当费用为正时停止增广。最后答案(求的是盈利)再取一次负即可。

    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 (dis[t] >= 0) return 0;
        //费用为正时停止增广
        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 kase; cin >> kase; for(int kk=1;kk<=kase;kk++) {
            maxflow = mincost = 0;
            mem(e, 0);
            mem(head, 0);
            mem(pre, 0);
            cnt_e = 1;
    
            int cost;
            //1个月cost元
            cin >> n >> cost;
            s = n * 2 + 1; t = n * 2 + 2;
            for (int i = 1; i <= n; i++) {
                int a, b, c, d;
                cin >> a >> b >> c >> d >> keep[i];
                //生产成本,最大生产量,售价,最大销售量
                addf(s, i, b, a);
                for (int j = i; j <= min(n, i + keep[i]); j++) {
                    addf(i, n + j, b, (j - i) * cost);
                }
                addf(i + n, t, d, -c);
            }
            MCMF();
            cout << "Case " << kk << ": " << -mincost << endl;
        }
        return 0;
    }
    
  • 相关阅读:
    **RESTful API版本控制策略
    HTTP协议header标头详解
    $headers = $this->input->request_headers();返回请求头(header)数组
    ****Web API 版本控制的几种方式
    ****RESTful API 设计最佳实践(APP后端API设计参考典范)
    php怎么获取checkbox复选框的内容?
    Linux中Samba详细安装【转】
    linux中serial driver理解【转】
    Linux内核中进程上下文、中断上下文、原子上下文、用户上下文的理解【转】
    八、mini2440裸机程序之UART(2)UART0与PC串口通信【转】
  • 原文地址:https://www.cnblogs.com/streamazure/p/13915862.html
Copyright © 2011-2022 走看看