Cod sursa(job #2529480)

Utilizator AlexLuchianovAlexandru Luchianov AlexLuchianov Data 23 ianuarie 2020 16:13:01
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.3 kb
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <fstream>

using namespace std;

ifstream in ("maxflow.in");
ofstream out ("maxflow.out");

#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) < (b)) ? (b) : (a))
using ll = long long;

class Graph{
private:
  int const inf = 1000000000;
  int n;

  struct Edge{
    int to;
    int flow;
    int cap;
    int rev;
  };
  vector<vector<Edge>> g;
  vector<int> level;
  vector<int> rem;

  int source, sink;
public:
  Graph(int n){
    this->n = n;
    g.resize(1 + n);
    level.resize(1 + n);
    rem.resize(1 + n);

    for(int i = 1;i <= n; i++)
      g[i].clear();
    source = 1;
    sink = n;
  }

  void addEdge(int x, int y, int cap){
    g[x].push_back({y, 0, cap, g[y].size()});
    g[y].push_back({x, 0, 0, g[x].size() - 1});
  }

  bool BFS(){
    for(int i = 1; i <= n; i++)
      level[i] = -1;
    queue<int> q;
    q.push(source);
    level[source] = 0;

    while(0 < q.size()){
      int node = q.front();
      q.pop();
      for(int h = 0; h < g[node].size(); h++){
        Edge e = g[node][h];
        if(e.flow < e.cap && level[e.to] == -1){
          level[e.to] = level[node] + 1;
          q.push(e.to);
        }
      }
    }
    return 0 <= level[sink];
  }

  int DFS(int node, int deltaflow){
    if(node == sink)
      return deltaflow;
    else {
      for(int &h = rem[node]; h < g[node].size(); h++){
        Edge &e = g[node][h];
        if(e.flow < e.cap && level[node] + 1 == level[e.to]){
          int delta = DFS(e.to, MIN(deltaflow, e.cap - e.flow));
          if(0 < delta){
            e.flow += delta;
            g[e.to][e.rev].flow -= delta;
            return delta;
          }
        }
      }
      return 0;
    }
  }

  ll maxflow(){
    ll result = 0;
    while(BFS()){
      for(int i = 1;i <= n; i++)
        rem[i] = 0;
      int delta = 0;
      do {
        result += delta;
        delta = DFS(source, inf);
      } while(0 < delta);
    }
    return result;
  }
};

int main()
{
  int n, m;
  in >> n >> m;
  Graph graph(n);
  for(int i = 1;i <= m; i++){
    int x, y, cap;
    in >> x >> y >> cap;
    graph.addEdge(x, y, cap);
  }
  out << graph.maxflow();
  return 0;
}