Cod sursa(job #3297365)

Utilizator Arhiva_Educationala_2Arhiva Educationala doi Arhiva_Educationala_2 Data 22 mai 2025 15:25:02
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2 kb
#include <stdio.h>

#include <queue>
#include <vector>
#include <algorithm>

namespace Flow {
  const int MAXN = 1000;
  constexpr int INF = 1e9;
  
  std::vector<int> adj[MAXN];
  int cap[MAXN][MAXN];
  int dist[MAXN];
  int n;

  void init( int N ) { n = N; }
  void push_edge( int a, int b, int _cap ) {
    adj[a].push_back( b );
    adj[b].push_back( a );

    cap[a][b] += _cap;
    // cap[b][a] += 0;
  }

  bool bfs( int src, int dest ) {
    for( int i = 0; i < n; i++ )
      dist[i] = +INF;

    std::queue<int> q({ src });
    dist[src] = 0;
    while( !q.empty() ){
      int u = q.front();
      q.pop();

      for( int v : adj[u] )
        if( cap[u][v] && dist[u] + 1 < dist[v] ){
          dist[v] = dist[u] + 1;
          q.push( v );
        }
    }

    return dist[dest] < +INF;
  }

  int search_begin[MAXN];
  int dinic( int u, int dest, int push ) {
    if( !push ) return 0;
    if( u == dest ) return push;

    for( int &i = search_begin[u]; i < (int)adj[u].size(); i++ ){
      int v = adj[u][i];
      
      if( !cap[u][v] ) continue;
      if( dist[u] + 1 != dist[v] ) continue;

      int try_push = dinic( v, dest, std::min( push, cap[u][v] ) );
      if( !try_push ) continue;

      cap[u][v] -= try_push;
      cap[v][u] += try_push;
      return try_push;
    }

    return 0;
  }

  int push_flow( int src, int dest ) {
    int flow = 0;
    while( bfs( src, dest ) ){
      for( int i = 0; i < n; i++ )
        search_begin[i] = 0;

      int push = 0;
      while( (push = dinic( src, dest, +INF )) )
        flow += push;
    }

    return flow;
  }
}

int main() {
  FILE *fin = fopen( "maxflow.in", "r" );
  FILE *fout = fopen( "maxflow.out", "w" );

  int n, m;
  fscanf( fin, "%d%d", &n, &m );
  int src = 0, dest = n - 1;

  Flow::init( n );
  for( int i = 0; i < m; i++ ){
    int a, b, cap;
    fscanf( fin, "%d%d%d", &a, &b, &cap );
    Flow::push_edge( --a, --b, cap );
  }

  int flow = Flow::push_flow( src, dest );
  fprintf( fout, "%d\n", flow );

  fclose( fin );
  fclose( fout );
  return 0;
}