Cod sursa(job #3262770)

Utilizator IanisBelu Ianis Ianis Data 11 decembrie 2024 16:05:49
Problema Flux maxim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.38 kb
#pragma GCC optimize("Ofast")
#ifndef LOCAL
#include <bits/stdc++.h>
#else
#include <iostream>
#endif

using namespace std;

#define sz(a) int((a).size())
#define all(a) (a).begin(), (a).end()

const int NMAX = 1005;
const int INF = 1e9+5;

struct Dinic {
   struct Edge {
      int x, cap, other;
   };

   int n;
   vector<vector<Edge>> e;
   vector<int> last, dist;
   int S, T;

   Dinic() {
      S = add_node();
      T = add_node();
   }

   int add_node() {
      e.emplace_back();
      dist.emplace_back();
      last.emplace_back();
      return sz(e) - 1;
   }

   void add_edge(int x, int y, int cap) {
      e[x].push_back({ y, cap, sz(e[y]) });
      e[y].push_back({ x, 0, sz(e[x]) - 1 });
   }

   bool bfs() {
      fill(all(dist), INF);
      queue<int> q;
      q.push(S);
      dist[S] = 0;

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

         for (auto &[ u, cap, _ ] : e[x]) {
            if (cap && dist[u] == INF) {
               dist[u] = dist[x] + 1;
               q.push(u);
            }
         }
      }

      return dist[T] != INF;
   }

   int dfs(int x, int flow = INF) {
      if (flow == 0) return 0;
      if (x == T) {
//         cout << flow << endl;
         return flow;
      }

      int ret = 0;

      for (; last[x] < sz(e[x]); last[x]++) {
         auto &it = e[x][last[x]];
         if (it.cap && dist[it.x] == dist[x] + 1) {
//            cout << x << ' ' << it.x << " nigger " << it.cap << endl;
            int f = dfs(it.x, min(flow, it.cap));

            it.cap -= f;
            e[it.x][it.other].cap += f;

            ret += f;
         }
      }

      return ret;
   }

   int max_flow() {
      int flow = 0;

      while (bfs()) {
         fill(all(last), 0);
         while (int f = dfs(S)) {
            flow += f;
         }
      }

      return flow;
   }
};

int n, m;
int a[NMAX];

signed main() {
#ifdef LOCAL
   freopen("input.txt", "r", stdin);
#else
   freopen("maxflow.in", "r", stdin);
   freopen("maxflow.out", "w", stdout);
#endif

   ios_base::sync_with_stdio(false);
   cin.tie(0);
   cout.tie(0);

   cin >> n >> m;

   Dinic dinic;
   a[1] = dinic.S;
   a[n] = dinic.T;

   for (int i = 2; i < n; i++) {
      a[i] = dinic.add_node();
   }

   for (int i = 1; i <= m; i++) {
      int x, y, c;
      cin >> x >> y >> c;
      dinic.add_edge(a[x], a[y], c);
   }

   cout << dinic.max_flow() << endl;
   
   return 0;
}