Cod sursa(job #3230029)

Utilizator RolandPetreanPetrean Roland RolandPetrean Data 18 mai 2024 20:50:19
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.95 kb
// https://infoarena.ro/problema/maxflow
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'

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

const int INF = 1e9;

struct Dinic {
  struct Edge {
    int from, to, capacity, next_from_edge;
  };

  int n;
  vector<Edge> edges;
  vector<int> first_edge, level;

  Dinic(int n) {
    this->n = n;
    first_edge.assign(n + 1, -1);
  }

  void add_edge(int from, int to, int capacity) {
    edges.push_back({from, to, capacity, first_edge[from]});
    first_edge[from] = edges.size() - 1;

    edges.push_back({to, from, 0, first_edge[to]});
    first_edge[to] = edges.size() - 1;
  }

  bool calculate_levels(int source, int sink) {
    level.assign(n + 1, INF);
    queue<int> q;
    level[source] = 0;
    q.push(source);

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

      for (int e = first_edge[v]; e != -1; e = edges[e].next_from_edge) {
        if (edges[e].capacity > 0 && level[edges[e].to] == INF) {
          level[edges[e].to] = level[v] + 1;
          q.push(edges[e].to);
        }
      }
    }

    return (level[sink] != INF);
  }

  int try_push_flow(int v, int sink, int f) {
    if (v == sink) return f;
    
    int total_pushed = 0;
    for (int e = first_edge[v]; e != -1; e = edges[e].next_from_edge) {
      if (edges[e].capacity > 0 && level[edges[e].to] == level[v] + 1) {
        int pushed = try_push_flow(edges[e].to, sink, min(f, edges[e].capacity));
        f -= pushed;
        total_pushed += pushed;

        edges[e].capacity -= pushed;
        edges[e ^ 1].capacity += pushed;
      }
    }

    return total_pushed;
  }

  int max_flow(int source, int sink) {
    int f = 0;
    while (calculate_levels(source, sink)) f += try_push_flow(source, sink, INF);
    return f;
  }
};

int main() {
  int n, m;
  fin >> n >> m;

  Dinic d(n);

  for (int i = 0; i < m; ++i) {
    int u, v, c;
    fin >> u >> v >> c;
    d.add_edge(u, v, c);
  }

  fout << d.max_flow(1, n);
}