Cod sursa(job #2896993)

Utilizator giotoPopescu Ioan gioto Data 1 mai 2022 21:45:38
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.94 kb
#include <bits/stdc++.h>
using namespace std;

namespace Dinic {
  const int NMAX = 1000;
  const int INF = 2e9;

  struct edge {
    int x, c, f;
    int rev;
  };

  int n, s, d;
  vector <int> lev;
  vector <int> rem;
  vector <vector <edge>> v;
  void init(int _n, int _s, int _d) {
    n = _n; 
    s = _s;
    d = _d;

    v.resize(_n + 1);
    lev.resize(_n + 1);
    rem.resize(_n + 1);
  }

  void add_edge(int x, int y, int c) {
    v[x].push_back({y, c, 0, (int)v[y].size()});
    v[y].push_back({x, 0, 0, (int)v[x].size() - 1});
  }

  bool bfs(int cost) {
    static queue <int> q;
    fill(lev.begin(), lev.end(), 0);

    q.push(s);
    lev[s] = 1;

    while (!q.empty()) {
      int nod = q.front();
      q.pop();

      if (nod == d)
        continue;

      for (auto it : v[nod]) {
        if (it.c - it.f >= cost && it.f < it.c && lev[it.x] == 0) {
          lev[it.x] = lev[nod] + 1;
          q.push(it.x);
        }
      }
    }

    return (lev[d] != 0); 
  }

  int dfs(int nod = s, int flow = INF) {
    if (nod == d)
      return flow;
    
    for (int &i = rem[nod]; i < v[nod].size() ; ++i) {
      auto &it = v[nod][i];
      if (lev[it.x] == lev[nod] + 1 && it.f < it.c) { 
        int add = dfs(it.x, min(flow, it.c - it.f));
        if (add == 0)
          continue;

        it.f += add;
        v[it.x][it.rev].f -= add;
        return add;
      }
    }

    return 0;
  }

  int get_flow() {
    int flow = 0;

    for (int pas = 16; pas >= 0 ; --pas) {
      while (bfs(1 << pas)) {
        fill(rem.begin(), rem.end(), 0);
        int step_flow = 0;
        while (step_flow = dfs())
          flow += step_flow;
      }
    }

    return flow;
  }
}

int main() {
  ifstream fin("maxflow.in");
  ofstream fout("maxflow.out");

  int n, m;
  fin >> n >> m;

  Dinic::init(n, 1, n);
  for (int i = 1; i <= m ; ++i) {
    int x, y, c;
    fin >> x >> y >> c;
    Dinic::add_edge(x, y, c);
  }

  fout << Dinic::get_flow() << '\n';

  return 0;
}