P4014 分配问题 网络流

P4014 分配问题

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 const int maxn = 305, 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 c[maxn][maxn];
 68 int main() {
 69     int n; scanf("%d",&n);
 70     int s = 2*n+1, t = 2*n+2;
 71 
 72     for (int i = 1; i <= n; ++i) {
 73         for (int j = 1; j <= n; ++j) {
 74             scanf("%d",&c[i][j]);
 75         }
 76     }
 77 
 78     /// 最小总效益
 79     mcmf.init(2*n+2);
 80     for (int i = 1; i <= n; ++i) {
 81         for (int j = 1; j <= n; ++j) {
 82             mcmf.AddEdge(i,j+n,1,c[i][j]);
 83         }
 84     }
 85     for (int i = 1; i <= n; ++i) {
 86         mcmf.AddEdge(s,i,1,0);
 87         mcmf.AddEdge(i+n,t,1,0);
 88     }
 89     int ans = mcmf.mincost(s,t);
 90     printf("%d\n",ans);
 91 
 92     /// 最大总效益
 93     mcmf.init(2*n+2);
 94     for (int i = 1; i <= n; ++i) {
 95         for (int j = 1; j <= n; ++j) {
 96             mcmf.AddEdge(i,j+n,1,-c[i][j]);
 97         }
 98     }
 99     for (int i = 1; i <= n; ++i) {
100         mcmf.AddEdge(s,i,1,0);
101         mcmf.AddEdge(i+n,t,1,0);
102     }
103     ans = mcmf.mincost(s,t);
104     printf("%d\n",-ans);
105     return 0;
106 }

 

上一篇:单源最短路(手写堆+位运算优化+卡常+O2 = Luogu排名最后一页...)


下一篇:P4014 分配问题(网络流24题 最大最小费用流)