Cod sursa(job #1850007)

Utilizator msciSergiu Marin msci Data 18 ianuarie 2017 01:20:20
Problema Flux maxim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.55 kb
#include <bits/stdc++.h>

using namespace std;

struct Dinic {
  static const int InfCapacity = 0x3f3f3f3f;

  struct Edge {
    int to;
    int capacity;
    int rev;
  };

  vector< vector<Edge> > g;

  void init(int n) {
    g.assign(n, vector<Edge>());
  } 

  void add(int i, int j, int capacity) {
    Edge e, f;
    e.to = j, f.to = i;
    e.capacity = capacity, f.capacity = 0;
    g[i].push_back(e); g[j].push_back(f);
    g[i].back().rev = (int) g[j].size() - 1;
    g[j].back().rev = (int) g[i].size() - 1;
  }

  void addB(int i, int j, int capacity) {
    Edge e, f;
    e.to = j, f.to = i;
    e.capacity = capacity, f.capacity = capacity;
    g[i].push_back(e); g[j].push_back(f);
    g[i].back().rev = (int) g[j].size() - 1;
    g[j].back().rev = (int) g[i].size() - 1;
  }

  int maximum_flow(int s, int t) {
    int n = (int) g.size();
    vector<int> level(n);
    int total = 0;
    bool update;
    do {
      update = false;
      fill(level.begin(), level.end(), -1);
      level[s] = 0;
      queue<int> q;
      q.push(s);
      for (int d = n; !q.empty() && level[q.front()] < d; ) {
        int u = q.front();
        q.pop();
        if (u == t) {
          d = level[u];
        }
        for (Edge& e : g[u]) {
          if (e.capacity > 0 && level[e.to] == -1) {
            q.push(e.to);
            level[e.to] = level[u] + 1;
          }
        }
      }
      vector<int> iter(n);
      for (int i = 0; i < n; i++) {
        iter[i] = (int) g[i].size() - 1;
      }
      while (true) {
        int f = augment(level, iter, s, t, InfCapacity);
        if (f == 0) {
          break;
        }
        total += f;
        update = true;
      }
    } while (update);
    return total;
  }

  int augment(vector<int>& level, vector<int>& iter, int u, int t, int f) {
    if (u == t || f == 0) {
      return f;
    }
    int lv = level[u];
    if (lv == -1) {
      return 0;
    }
    level[u] = -1;
    for (; iter[u] >= 0; --iter[u]) {
      Edge& e = g[u][iter[u]];
      if (level[e.to] <= lv) {
        continue;
      }
      int l = augment(level, iter, e.to, t, min(f, e.capacity));
      if (l == 0) continue;
      e.capacity -= l;
      g[e.to][e.rev].capacity += l;
      level[u] = lv;
      return l;
    }
    return 0;
  }
};

int main() {
  freopen("maxflow.in", "r", stdin);
  freopen("maxflow.out", "w", stdout);
  int n, m;
  scanf("%d %d", &n, &m);
  Dinic mf;
  mf.init(n);
  for (int i = 0; i < m; i++) {
    int x, y, c;
    scanf("%d %d %d", &x, &y, &c);
    x--, y--;
    mf.add(x, y, c);
  }
  printf("%d\n", mf.maximum_flow(0, n - 1));
  return 0;
}