Cod sursa(job #2813689)

Utilizator iancupoppPopp Iancu Alexandru iancupopp Data 7 decembrie 2021 07:16:13
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.12 kb
#include <fstream>
#include <vector>
#include <cstring>
#include <queue>

using namespace std;

const int N = 1e3 + 5;

struct Edge {
  int from, to;
  int cap;
};

class Dinic {
private:
  vector<vector<int>> gr;
  vector<Edge> ed;
  int *nxtEdge, *lvl;
  int nodeCnt, src, dst, maxFlow;
public:
  Dinic(int n, int s, int d): nodeCnt(n), src(s), dst(d), maxFlow(0) {
    gr = vector<vector<int>>(n + 1);
    nxtEdge = new int[n + 1];
    lvl = new int[n + 1];
  }
  void addEdge(int from, int to, int cap) {
    ed.push_back({from, to, cap});
    gr[from].push_back(ed.size() - 1);
    ed.push_back({to, from, 0});
    gr[to].push_back(ed.size() - 1);
  }
  bool bfs() {
    queue<int> q;
    q.push(src);
    memset(lvl, 0, (nodeCnt + 1) * sizeof(int));
    lvl[src] = 1;
    while (!q.empty()) {
      auto node = q.front();
      q.pop();
      if (node == dst)
        break;
      for (auto e: gr[node])
        if (lvl[ed[e].to] == 0 && ed[e].cap > 0) {
          lvl[ed[e].to] = lvl[node] + 1;
          q.push(ed[e].to);
        }
    }
    return lvl[dst] != 0;
  }
  int dfs(int node, int minFlow) {
    if (node == dst)
      return minFlow;
    for (;nxtEdge[node] < gr[node].size(); ++nxtEdge[node]) {
      int e = gr[node][nxtEdge[node]];
      if (ed[e].cap == 0) continue;
      if (lvl[ed[e].to] != lvl[node] + 1) continue;
      int flow = dfs(ed[e].to, min(minFlow, ed[e].cap));
      if (flow != -1) {
        ed[e].cap -= flow;
        ed[e ^ 1].cap += flow;
        return flow;
      }
    }
    return -1;
  }
  int getMaxFlow() {
    while (bfs()) {
      memset(nxtEdge, 0, (nodeCnt + 1) * sizeof(int));
      int flow = dfs(src, 2e9);
      while (flow != -1) {
        maxFlow += flow;
        flow = dfs(src, 2e9);
      }
    }
    return maxFlow;
  }
};

int main() {
  ifstream cin("maxflow.in");
  ofstream cout("maxflow.out");
  int n, m;
  cin >> n >> m;
  Dinic d(n, 1, n);
  while (m--) {
    int x, y, c;
    cin >> x >> y >> c;
    d.addEdge(x, y, c);
  }
  cin.close();
  cout << d.getMaxFlow() << "\n";
  cout.close();
  return 0;
}