Cod sursa(job #3224162)

Utilizator andreic06Andrei Calota andreic06 Data 14 aprilie 2024 20:53:18
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.26 kb
#include <bits/stdc++.h>

using namespace std;
ifstream in ("maxflow.in");
ofstream out ("maxflow.out");

const int V_MAX = 1000;
const int E_MAX = 5000;
const int NONE = -1;

const int myINF = 2e9;
struct MaxFlow {
   int V, E;

   int source, sink;
   int cap[1 + V_MAX][1 + V_MAX];
   vector<int> g[1 + V_MAX];

   void add_edge (int a, int b, int this_cap) {
       g[a].push_back (b);
       g[b].push_back (a);
       cap[a][b] = this_cap;
   }

   int dist[1 + V_MAX];
   void resetDist (void) {
      for (int node = 1; node <= V; node ++)
         dist[node] = NONE;
   }

   bool bfs (void) {
      resetDist ();

      queue<int> q;
      dist[source] = 0;
      q.push (source);

      while (!q.empty ()) {
         int root = q.front ();
         q.pop ();
         for (int node : g[root]) {
            if (dist[node] == NONE && cap[root][node] > 0) {
              dist[node] = dist[root] + 1;
              q.push (node);
            }
         }
      }
      return (dist[sink] != NONE);
   }

   int ptr[1 + V_MAX];
   void resetPtr (void) {
      for (int node = 1; node <= V; node ++)
         ptr[node] = 0;
   }

   int dfs (int root, int pushed) {
      if (pushed == 0) return 0;
      if (root == sink) return pushed;

      for (int& i = ptr[root]; i < (int) g[root].size (); i ++) {
         int node = g[root][i];

         if (cap[root][node] == 0 || dist[root] + 1 != dist[node]) continue;
         int bottleneck = dfs (node, min (pushed, cap[root][node]));
         if (bottleneck == 0) continue;
         cap[root][node] -= bottleneck;
         cap[node][root] += bottleneck;
         return bottleneck;
      }
      return 0;
   }

   int solveFlow (void) {
      int flow = 0;
      while (bfs ()) {
         int addFlow;
         do {
           addFlow = dfs (source, myINF);
           flow += addFlow;
         }
         while (addFlow > 0);

         resetDist ();
         resetPtr ();
      }
      return flow;
   }
} MF;

int main()
{
   in >> MF.V >> MF.E;
   for (int i = 1; i <= MF.E; i ++) {
      int a, b, this_cap; in >> a >> b >> this_cap;
      MF.add_edge (a, b, this_cap);
   }
   MF.source = 1, MF.sink = MF.V;
   out << MF.solveFlow ();

    return 0;
}