Cod sursa(job #2803062)

Utilizator mircea_007Mircea Rebengiuc mircea_007 Data 19 noiembrie 2021 12:55:21
Problema Flux maxim Scor 70
Compilator c-64 Status done
Runda Arhiva educationala Marime 2.37 kb
#include <stdio.h>
#include <ctype.h>

// Program de Mircea Rebengiuc
// inceput pe 2021.11.18

// solutie neoptimizata, 70p

#define MAXN 1000
#define MAXM 5000
#define NIL  -1

int list[MAXN];
int adj[MAXM];
int next[MAXM];

int prev[MAXN];// drumul bfs

int remaining[MAXN][MAXN];// capacitate - flux

// bfs
int q[MAXN];// mai e nevoie de coada circulara cand nu vom trece de MAXQ niciodata?
int viz[MAXN];
int p, u;

int bfs( int n, int from, int to ){
  int i, node;

  for( i = 0 ; i < n ; i++ )
    viz[i] = 0;
  viz[from] = 1;

  p = u = 0;

  q[u++] = from;
  while( p < u /*&& q[p] != to*/ ){
    if( (node = q[p++]) != to ){
      i = list[node];

      while( i != NIL ){
        if( !viz[adj[i]] && remaining[node][adj[i]] > 0 ){
          q[u++] = adj[i];
          prev[adj[i]] = node;
          viz[adj[i]] = 1;
        }
        
        i = next[i];
      }
    }
  }

  return viz[to];// ca sa pot sa pun direct while( bfs(..) ){}
}

FILE *fin, *fout;

static inline int fgetint(){
  int n = 0, ch;

  while( !isdigit(ch = fgetc(fin)) );
  do
    n = n * 10 + ch - '0';
  while( isdigit(ch = fgetc(fin)) );

  return n;
}

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

  int n, m, i, j, from, to, flux, maxdelta;

  n = fgetint();
  for( i = 0 ; i < n ; i++ )
    list[i] = NIL;
  
  i = 0;
  for( m = fgetint() ; m-- ; ){
    from = fgetint() - 1;
    to = fgetint() - 1;
    remaining[from][to] = fgetint();

    // from -> to
    next[i] = list[from];
    adj[i] = to;
    list[from] = i++;

    // to -> from
    next[i] = list[to];
    adj[i] = from;
    list[to] = i++;
  }
  
  from = 0;
  to = n - 1;

  flux = 0;
  while( bfs(n, from, to) ){
    for( j = list[to] ; j != NIL ; j = next[j] ){
      if( remaining[adj[j]][to] > 0 && viz[adj[j]] ){
        prev[to] = adj[j];// incercam drumul: from -> ... -> adj[j] -> to
        maxdelta = 2000000000;

        for( i = to ; i != from ; i = prev[i] )
          maxdelta = remaining[prev[i]][i] < maxdelta ? remaining[prev[i]][i] : maxdelta;

        if( maxdelta != 0 ){// schimbam ceva?
          for( i = to ; i != from ; i = prev[i] ){
            remaining[prev[i]][i] -= maxdelta;// fluxul creste, diferenta scade
            remaining[i][prev[i]] += maxdelta;
          }
        }

        flux += maxdelta;
      }
    }
  }

  fprintf(fout, "%d\n", flux);

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