Cod sursa(job #3259824)

Utilizator mircea_007Mircea Rebengiuc mircea_007 Data 27 noiembrie 2024 22:33:43
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.38 kb
#include <stdio.h>
#include <vector>
#include <queue>

const int MAXN = 1000;
const int INF = 1e9;

namespace Flow {
  struct Edge {
    int u, cap, rev_idx;
    Edge( int u, int cap, int ridx ): u(u), cap(cap), rev_idx(ridx) {}
  };

  std::vector<Edge> adj[MAXN];
  int dist[MAXN];
  int n;

  void init( int N ) {
    n = N;
    for( int i = 0; i < n; i++ )
      adj[i].clear();
  }

  void push_edge( int from, int to, int cap ) {
    adj[from].emplace_back( to, cap, (int)adj[to].size() );
    adj[to].emplace_back( from, 0, (int)adj[from].size() - 1 );
  }

  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( Edge e : adj[u] ) {
        if( e.cap && dist[u] + 1 < dist[e.u] ){
          dist[e.u] = dist[u] + 1;
          q.push( e.u );
        }
      }
    }

    return dist[dest] < +INF;
  }

  int begin_idx[MAXN];
  void init_dinic() {
    for( int i = 0; i < n; i++ )
      begin_idx[i] = 0;
  }

  // returneaza cat flux a pompat
  int dinic( int src, int dest, int push ) { // push este valoarea maxima de flux pe care avem voie sa o pompam
    if( !push ) return 0;
    if( src == dest ) return push;

    for( int &idx = begin_idx[src]; idx < (int)adj[src].size(); idx++ ){
      int v = adj[src][idx].u;
      int C = adj[src][idx].cap;
      if( dist[v] != dist[src] + 1 || !C )
        continue;

      int try_push = dinic( v, dest, std::min( push, C ) );

      if( try_push ){
        //printf( "C = %d, pushed %d\n", C, try_push );
        adj[src][idx].cap -= try_push;
        adj[v][adj[src][idx].rev_idx].cap += try_push;
        return try_push;
      }
    }

    return 0;
  }

  int maxflow( int src, int dest ) {
    int ret = 0;

    while( bfs( src, dest ) ){
      init_dinic();

      int pushed = 0;
      while( (pushed = dinic( src, dest, +INF )) > 0 )
        ret += pushed;
    }

    return ret;
  }
}

int main() {
  FILE *fin = fopen( "maxflow.in", "r" );
  FILE *fout = fopen( "maxflow.out", "w" );
  
  int n, m;
  fscanf( fin, "%d%d", &n, &m );

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

    Flow::push_edge( a, b, cap );
  }

  fprintf( fout, "%d\n", Flow::maxflow( 0, n - 1 ) );

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