P4015 运输问题 最大/最小费用最大流

P4015 运输问题

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 const int maxn = 205, inf = 0x3f3f3f3f;
  4 struct Edge {
  5     int from, to, cap, flow, cost;
  6 };
  7 struct MCMF {
  8     int n, m, s, t;
  9     vector<Edge> edges;
 10     vector<int> G[maxn];
 11     int inq[maxn];
 12     int d[maxn];
 13     int p[maxn];
 14     int a[maxn];
 15 
 16     void init(int n) {
 17         this->n = n;
 18         for (int i = 1; i <= n; ++i) G[i].clear();
 19         edges.clear();
 20     }
 21 
 22     void AddEdge(int from, int to, int cap, int cost) {
 23         edges.push_back((Edge){from, to, cap, 0, cost});
 24         edges.push_back((Edge){to, from, 0, 0, -cost});
 25         m = edges.size();
 26         G[from].push_back(m-2);
 27         G[to].push_back(m-1);
 28     }
 29     bool BellmanFord(int s, int t, int& flow, int& cost) {
 30         for (int i = 1; i <= n; ++i) d[i] = inf;
 31         memset(inq, 0, sizeof(inq));
 32         d[s] = 0; inq[s] = 1; p[s] = 0; a[s] = inf;
 33 
 34         queue<int> que;
 35         que.push(s);
 36         while (!que.empty()) {
 37             int u = que.front(); que.pop();
 38             inq[u] = 0;
 39             for (int i = 0; i < G[u].size(); ++i) {
 40                 Edge& e = edges[G[u][i]];
 41                 if (e.cap > e.flow && d[e.to] > d[u] + e.cost) {
 42                     d[e.to] = d[u] + e.cost;
 43                     p[e.to] = G[u][i];
 44                     a[e.to] = min(a[u], e.cap-e.flow);
 45                     if (!inq[e.to]) { que.push(e.to); inq[e.to] = 1; }
 46                 }
 47             }
 48         }
 49         if (d[t] == inf) return false;
 50         flow += a[t];
 51         cost += d[t] * a[t];
 52         int u = t;
 53         while (u != s) {
 54             edges[p[u]].flow += a[t];
 55             edges[p[u]^1].flow -= a[t];
 56             u = edges[p[u]].from;
 57         }
 58         return true;
 59     }
 60     int mincost(int s, int t) {
 61         int flow = 0, cost = 0;
 62         while (BellmanFord(s, t, flow, cost));
 63         return cost;
 64     }
 65 }mcmf;
 66 int a[maxn], b[maxn], c[maxn][maxn];
 67 int main() {
 68     int m, n; scanf("%d%d",&m,&n);
 69     int s = m+n+1, t = m+n+2;
 70 
 71     for (int i = 1; i <= m; ++i) scanf("%d",&a[i]);
 72     for (int j = 1; j <= n; ++j) scanf("%d",&b[j]);
 73     for (int i = 1; i <= m; ++i) {
 74         for (int j = 1; j <= n; ++j) {
 75             scanf("%d",&c[i][j]);
 76         }
 77     }
 78     // 最小费用最大流
 79     mcmf.init(n+m+2);
 80     for (int i = 1; i <= m; ++i) {
 81         mcmf.AddEdge(s,i,a[i],0);
 82     }
 83     for (int i = 1; i <= m; ++i) {
 84         for (int j = 1; j <= n; ++j) {
 85             mcmf.AddEdge(i,j+m,inf,c[i][j]);
 86         }
 87     }
 88     for (int j = 1; j <= n; ++j) {
 89         mcmf.AddEdge(j+m,t,b[j],0);
 90     }
 91     printf("%d\n",mcmf.mincost(s,t));
 92 
 93     // 最大费用最大流
 94     mcmf.init(n+m+2);
 95     for (int i = 1; i <= m; ++i) {
 96         mcmf.AddEdge(s,i,a[i],0);
 97     }
 98     for (int i = 1; i <= m; ++i) {
 99         for (int j = 1; j <= n; ++j) {
100             mcmf.AddEdge(i,j+m,inf,-c[i][j]);
101         }
102     }
103     for (int j = 1; j <= n; ++j) {
104         mcmf.AddEdge(j+m,t,b[j],0);
105     }
106     printf("%d\n",-mcmf.mincost(s,t));
107     return 0;
108 }

 

posted @ 2019-11-03 13:11  麻辣猪仔  阅读(225)  评论(0编辑  收藏  举报