P4016 负载平衡问题

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 const int maxn = 1005, inf = 0x3f3f3f3f;
  4 struct Edge {
  5     int from, to, cap, flow, cost;
  6 };
  7
  8 struct MCMF {
  9     int n, m, s, t;
 10     vector<Edge> edges;
 11     vector<int> G[maxn];
 12     int inq[maxn];
 13     int d[maxn];
 14     int p[maxn];
 15     int a[maxn];
 16
 17     void init(int n) {
 18         this->n = n;
 19         for (int i = 1; i <= n; ++i) G[i].clear();
 20         edges.clear();
 21     }
 22
 23     void AddEdge(int from, int to, int cap, int cost) {
 24         edges.push_back((Edge){from, to, cap, 0, cost});
 25         edges.push_back((Edge){to, from, 0, 0, -cost});
 26         m = edges.size();
 27         G[from].push_back(m-2);
 28         G[to].push_back(m-1);
 29     }
 30     bool BellmanFord(int s, int t, int& flow, int& cost) {
 31         for (int i = 1; i <= n; ++i) d[i] = inf;
 32         memset(inq, 0, sizeof(inq));
 33         d[s] = 0; inq[s] = 1; p[s] = 0; a[s] = inf;
 34
 35         queue<int> que;
 36         que.push(s);
 37         while (!que.empty()) {
 38             int u = que.front(); que.pop();
 39             inq[u] = 0;
 40             for (int i = 0; i < G[u].size(); ++i) {
 41                 Edge& e = edges[G[u][i]];
 42                 if (e.cap > e.flow && d[e.to] > d[u] + e.cost) {
 43                     d[e.to] = d[u] + e.cost;
 44                     p[e.to] = G[u][i];
 45                     a[e.to] = min(a[u], e.cap-e.flow);
 46                     if (!inq[e.to]) { que.push(e.to); inq[e.to] = 1; }
 47                 }
 48             }
 49         }
 50         if (d[t] == inf) return false;
 51         flow += a[t];
 52         cost += d[t] * a[t];
 53         int u = t;
 54         while (u != s) {
 55             edges[p[u]].flow += a[t];
 56             edges[p[u]^1].flow -= a[t];
 57             u = edges[p[u]].from;
 58         }
 59         return true;
 60     }
 61     int mincost(int s, int t) {
 62         int flow = 0, cost = 0;
 63         while (BellmanFord(s, t, flow, cost));
 64         return cost;
 65     }
 66 }mcmf;
 67 int a[maxn];
 68 int main() {
 69     int n; scanf("%d",&n);
 70     int s = n+1, t = n+2, ave = 0;
 71     mcmf.init(n+2);
 72     for (int i = 1; i <= n; ++i) {
 73         scanf("%d",&a[i]);
 74         ave += a[i];
 75     }
 76     ave /= n;
 77     for (int i = 1; i <= n; ++i) {
 78         /// 如果仓库量小于平均值,则说明要从源点流入到该仓库
 79         if (a[i] < ave) mcmf.AddEdge(s,i,ave-a[i],0);
 80         /// 如果仓库量大于平均值,则说明要从该仓库流出到汇点
 81         if (a[i] > ave) mcmf.AddEdge(i,t,a[i]-ave,0);
 82     }
 83     /// 相邻点之间建立关系
 84     for (int i = 1; i <= n; ++i) {
 85         if (i == 1) {
 86             mcmf.AddEdge(i,i+1,inf,1);
 87             mcmf.AddEdge(i,n,inf,1);
 88             continue;
 89         }
 90         if (i == n) {
 91             mcmf.AddEdge(i,1,inf,1);
 92             mcmf.AddEdge(i,i-1,inf,1);
 93         }
 94         mcmf.AddEdge(i,i+1,inf,1);
 95         mcmf.AddEdge(i,i-1,inf,1);
 96     }
 97     int ans = mcmf.mincost(s,t);
 98     printf("%d\n",ans);
 99     return 0;
100 }
01-04 06:15