zoukankan      html  css  js  c++  java
  • 「网络流 24 题」负载平衡

    G 公司有 (n) 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等。如何用最少搬运量可以使 (n) 个仓库的库存数量相同。搬运货物时,只能在相邻的仓库之间搬运。

    这道题我们建立一个超级源点和超级汇点,源点向每个仓库连边,容量为仓库库存,仓库向汇点连边,容量为库存平均值。每一个点向左右连边,边权为inf。

    对于这些边,我们都需要建一条与他们方向相反,容量为 (0) ,费用为原边的相反数。

    然后直接跑一下最小费用最大流,费用即为解。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    
    using namespace std;
    
    int read() {
        int a = 0, x = 1;
        char ch = getchar();
        while (ch > '9' || ch < '0') {
            if (ch == '-')
                x = -1;
            ch = getchar();
        }
        while (ch >= '0' && ch <= '9') {
            a = a * 10 + ch - '0';
            ch = getchar();
        }
        return a * x;
    }
    const int N = 807, inf = 1e9 + 7;
    ;
    int n, arr[N], sum = 0;
    
    int s, t, pre1[N], pre2[N];
    
    int head[N], go[N], nxt[N], val[N], lim[N], cnt = -1;
    void add(int u, int v, int r, int w) {
        go[++cnt] = v;
        nxt[cnt] = head[u];
        head[u] = cnt;
        val[cnt] = w, lim[cnt] = r;
    }
    int dis[N], ins[N];
    bool SPFA(int pos) {
        memset(ins, 0, sizeof(ins));
        queue<int> q;
        for (int i = 1; i <= n + 1; i++) dis[i] = inf;
        dis[pos] = 0, ins[pos] = 1;
        q.push(pos);
        while (!q.empty()) {
            int u = q.front();
            q.pop();
            ins[u] = 0;
            //	printf("%d 
    ",u);
            for (int e = head[u]; ~e; e = nxt[e]) {
                int v = go[e];
                if (!lim[e])
                    continue;
                if (dis[v] > dis[u] + val[e]) {
                    dis[v] = dis[u] + val[e];
                    pre1[v] = u, pre2[v] = e;
                    if (!ins[v]) {
                        q.push(v);
                        ins[v] = 1;
                    }
                }
            }
        }
        return dis[t] != inf;
    }
    
    void print(int i) {
        if (i == s)
            printf("%d ", s);
        else {
            print(pre1[i]);
            printf("%d ", i);
        }
    }
    
    int main() {
        n = read();
        s = 0, t = n + 1;
        memset(head, -1, sizeof(head));
        memset(nxt, -1, sizeof(nxt));
        for (int i = 1; i <= n; i++) {
            arr[i] = read();
            //  add(0, i, arr[i], 0);
            //  add(i, 0, 0, 0);
            sum += arr[i];
        }
        sum /= n;
        for (int i = 1; i <= n; i++) {
            if (arr[i] < sum) {
                add(i, n + 1, sum - arr[i], 0);
                add(n + 1, i, 0, 0);
            } else {
                add(0, i, arr[i] - sum, 0);
                add(i, 0, 0, 0);
            }
            add(i, i % n + 1, inf, 1);
            add(i % n + 1, i, 0, -1);
            add(i % n + 1, i, inf, 1);
            add(i, i % n + 1, 0, -1);
        }
        int ans = 0;
        // printf("%d
    ",sum);
        while (SPFA(s)) {
            ///	printf("!");
            int tmp = inf;
            for (int i = t; i != s; i = pre1[i]) tmp = min(tmp, lim[pre2[i]]);
            ans += dis[t] * tmp;
            //     print(t);
            //    putchar('
    ');
            for (int i = t; i != s; i = pre1[i]) lim[pre2[i]] -= tmp, lim[pre2[i] ^ 1] += tmp;
            // printf("%d %d
    ",tmp,ans);
        }
        printf("%d", ans);
        return 0;
    }
    
  • 相关阅读:
    springmvc
    POJ 3683 Priest John's Busiest Day
    POJ 3678 Katu Puzzle
    HDU 1815 Building roads
    CDOJ UESTC 1220 The Battle of Guandu
    HDU 3715 Go Deeper
    HDU 3622 Bomb Game
    POJ 3207 Ikki's Story IV
    POJ 3648 Wedding
    HDU 1814 Peaceful Commission
  • 原文地址:https://www.cnblogs.com/nao-nao/p/13695207.html
Copyright © 2011-2022 走看看