Advertisement
Mlxa

TEAMBOOK max-flow

Nov 1st, 2019
256
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.92 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using long_type = long long;
  3. #define long long_type
  4. #define all(x) begin(x), end(x)
  5. using namespace std;
  6.  
  7. const int   max_n       = 1 << 17;
  8. const int   int_inf     = 0x3f3f3f3f;
  9. const long  long_inf    = 0x3f3f3f3f3f3f3f3f;
  10. const int   source      = max_n - 1;
  11. const int   sink        = max_n - 2;
  12.  
  13. struct edge {
  14.     long c, f;
  15.     int u, r;
  16.     edge(int _u, long _c, int _r) :
  17.         c(_c),
  18.         f(0),
  19.         u(_u),
  20.         r(_r) {}
  21. };
  22.  
  23. struct flow {
  24.     long lim;
  25.     int ptr[max_n], fw[max_n], bw[max_n];
  26.     vector<pair<int, int>> where;
  27.     vector<edge> g[max_n];
  28.     vector<int> bfsg[max_n];
  29.    
  30.     void add_edge(int v, int u, long w) {
  31.         where.emplace_back(v, (int)g[v].size());
  32.         g[v].emplace_back(u, w, (int)g[u].size());
  33.         g[u].emplace_back(v, 0, (int)g[v].size() - 1);
  34.     }
  35.     void bfs(int from, int dist[]) {
  36.         fill(all(ptr), 0);
  37.         fill(dist, dist + max_n, int_inf);
  38.         queue<int> q;
  39.         q.push(from);
  40.         dist[from] = 0;
  41.         while (q.size()) {
  42.             int v = q.front();
  43.             q.pop();
  44.             for (int u : bfsg[v]) {
  45.                 if (dist[u] > dist[v] + 1) {
  46.                     dist[u] = dist[v] + 1;
  47.                     q.push(u);
  48.                 }
  49.             }
  50.         }
  51.     }
  52.     long dfs(int v, long mn) {
  53.         if (v == sink) {
  54.             return mn;
  55.         }
  56.         for (; ptr[v] < (int)g[v].size(); ++ptr[v]) {
  57.             edge &e = g[v][ptr[v]];
  58.             edge &r = g[e.u][e.r];
  59.             if (fw[e.u] != fw[v] + 1 || bw[e.u] != bw[v] - 1 || e.c - e.f < lim) {
  60.                 continue;
  61.             }
  62.             long d = dfs(e.u, min(mn, e.c - e.f));
  63.             if (d) {
  64.                 e.f += d;
  65.                 r.f -= d;
  66.                 return d;
  67.             }
  68.         }
  69.         return 0;
  70.     }
  71.     long max_flow() {
  72.         long sum = 0;
  73.         for (lim = 1 << 30; lim >= 1; lim >>= 1) {
  74.             while (1) {
  75.                 for (int i = 0; i < max_n; ++i) {
  76.                     bfsg[i].clear();
  77.                 }
  78.                 for (int i = 0; i < max_n; ++i) {
  79.                     for (edge e : g[i]) {
  80.                         if (e.c - e.f >= lim) {
  81.                             bfsg[i].push_back(e.u);
  82.                         }
  83.                     }
  84.                 }
  85.                 bfs(source, fw);
  86.                 if (fw[sink] == int_inf) {
  87.                     break;
  88.                 }
  89.                 for (int i = 0; i < max_n; ++i) {
  90.                     bfsg[i].clear();
  91.                 }
  92.                 for (int i = 0; i < max_n; ++i) {
  93.                     for (edge e : g[i]) {
  94.                         if (e.c - e.f >= lim) {
  95.                             bfsg[e.u].push_back(i);
  96.                         }
  97.                     }
  98.                 }
  99.                 bfs(sink, bw);
  100.                 long cur = dfs(source, long_inf);
  101.                 while (cur) {
  102.                     sum += cur;
  103.                     cur = dfs(source, long_inf);
  104.                 }
  105.             }
  106.         }
  107.         return sum;
  108.     }
  109. } f;
  110.  
  111.  
  112. int main() {
  113. #ifdef LC
  114.     assert(freopen("input.txt", "r", stdin));
  115. #else
  116. #define TASK "flow2"
  117.     assert(freopen(TASK ".in", "r", stdin));
  118.     assert(freopen(TASK ".out", "w", stdout));
  119. #endif
  120.     ios::sync_with_stdio(0);
  121.     cin.tie(0);
  122.     int n, m;
  123.     cin >> n >> m;
  124.     for (int i = 0; i < m; ++i) {
  125.         int v, u, w;
  126.         cin >> v >> u >> w;
  127.         f.add_edge(v, u, w);
  128.     }
  129.     assert((int)f.where.size() == m);
  130.     f.add_edge(source, 1, long_inf);
  131.     f.add_edge(n, sink, long_inf);
  132.     cout << f.max_flow() << "\n";
  133.     for (int i = 0; i < m; ++i) {
  134.         pair<int, int> p = f.where[i];
  135.         edge &e = f.g[p.first][p.second];
  136.         cout << e.f << "\n";
  137.     }
  138.     cerr << 1000 * clock() / CLOCKS_PER_SEC << endl;
  139.     return 0;
  140. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement