Cod sursa(job #2536395)

Utilizator AlexPop28Pop Alex-Nicolae AlexPop28 Data 1 februarie 2020 21:34:55
Problema Flux maxim Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.09 kb
#include <bits/stdc++.h>
#define dbg() cerr <<
#define name(x) (#x) << ": " << (x) << ' ' <<

using namespace std;

struct Dinic {
  struct Edge {
    int to, cap, flow, nxt;
    Edge(int to_, int cap_, int flow_, int nxt_) :
      to(to_), cap(cap_), flow(flow_), nxt(nxt_) {}
  };
  int src, dst;
  vector<Edge> edges;
  vector<int> adj, idx, dist;
  Dinic(int n) : adj(n, -1), dist(n) {}

  void Add(int from, int to, int cap) {
    edges.emplace_back(to, cap, 0, adj[from]);
    adj[from] = edges.size() - 1;
  }
  void AddEdge(int from, int to, int cap) {
    Add(from, to, cap);
    Add(to, from, 0);
  }

  bool BFS() {
    static vector<int> q;
    fill(dist.begin(), dist.end(), -1);
    dist[src] = 0;
    q = {src};
    for (int it = 0; it < (int)q.size(); ++it) {
      int node = q[it];
      auto e = edges[adj[node]];

      while (true) {
        if (dist[e.to] == -1 && e.flow < e.cap) {
          dist[e.to] = dist[node] + 1;
          q.emplace_back(e.to);
        }
        if (e.nxt == -1) break;
        e = edges[e.nxt];
      }
    }
    return dist[dst] != -1;
  }

  int DFS(int node, int flow) {
    if (flow == 0) return 0;
    if (node == dst) return flow;

    for (int &id = idx[node]; id != -1; id = edges[id].nxt) {
      auto e = edges[id];
      if (dist[e.to] == dist[node] + 1) {
        if (int delta = DFS(e.to, min(flow, e.cap - e.flow))) {
          edges[id].flow += delta;
          edges[1 ^ id].flow += delta;
          return delta;
        }
      }
    }
    return 0;
  }

  int Compute(int source, int sink) {
    src = source, dst = sink; int flow = 0;
    while (BFS()) {
      idx = adj;
      while (int delta = DFS(src, (int)1e9 + 5))
        flow += delta;
    }
    return flow;
  }
};

int main() {
  ifstream cin("maxflow.in");
  ofstream cout("maxflow.out");
  ios::sync_with_stdio(0);
  cin.tie(0);

  int n, m; cin >> n >> m;
  Dinic nw(n);
  for (int i = 0; i < m; ++i) {
    int a, b, c; cin >> a >> b >> c; --a, --b;
    nw.AddEdge(a, b, c);
  }
  cout << nw.Compute(0, n - 1) << endl;
}