Cod sursa(job #2918526)

Utilizator mircea_007Mircea Rebengiuc mircea_007 Data 11 august 2022 19:48:28
Problema Flux maxim de cost minim Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.77 kb
// This program was written by Mircea Rebengiuc
// on 11.08.2022
// for problem fmcm

#include <stdio.h>
#include <ctype.h>

#include <vector>
#include <set>   // Djikstra

#define MAXN 350
#define INF 2000000000
#define NIL -1
#define mp std::make_pair
#define magic_sauce inline __attribute__((always_inline))

int rem[MAXN][MAXN];// cap - flux
int prev[MAXN];
int dist[MAXN];
int viz[MAXN];
int icost[MAXN][MAXN];
int cost[MAXN][MAXN];
std::vector<int> adj[MAXN];

std::set<std::pair<int, int>> heap;

magic_sauce int min( int a, int b ){ return a < b ? a : b; }

void fck_it_lets_do_roy_floyd_hashtag_4_da_memez( int n, int start ){
  int i, j, k;
  int rfdist[MAXN][MAXN];

  for( i = 0 ; i < n ; i++ ){
    for( j = 0 ; j < n ; j++ )
      rfdist[i][j] = +INF;
    rfdist[i][i] = 0;
  }

  for( i = 0 ; i < n ; i++ )
    for( int u : adj[i] )
      rfdist[i][u] = icost[i][u];

  for( k = 0 ; k < n ; k++ )
    for( i = 0 ; i < n ; i++ )
      for( j = 0 ; j < n ; j++ )
        if( rfdist[i][k] + rfdist[k][j] < rfdist[i][j] )
          rfdist[i][j] = rfdist[i][k] + rfdist[k][j];

  for( i = 0 ; i < n ; i++ )
    dist[i] = cost[start][i];

  for( i = 0 ; i < n ; i++ )
    for( int u : adj[i] )
      cost[i][u] += icost[i][u] + dist[i] - dist[u];
}

int djikstra( int n, int start, int end ){
  int u;

  for( u = 0 ; u < n ; u++ ){
    viz[u] = 0;
    prev[u] = NIL;
    dist[u] = +INF;
  }

  heap.clear();
  heap.insert( mp( 0, start ) );
  dist[start] = 0;
  prev[start] = NIL;
  while( (u = heap.begin()->second) != end && heap.size() ){
    viz[u] = 1;
    heap.erase( heap.begin() );

    for( int i : adj[u] )
      if( !viz[i] && rem[u][i] > 0 ){
        if( dist[u] + cost[u][i] < dist[i] ){
          heap.erase( mp( dist[i], i ) );

          dist[i] = dist[u] + cost[u][i];
          prev[i] = u;

          heap.insert( mp( dist[i], i ) );
        }
      }
  }

  return u == end;
} 

FILE *fin, *fout;

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

  int n, m, i, j, src, dest, maxadd;
  int total;
  
  fscanf( fin, "%d%d%d%d", &n, &m, &src, &dest );
  src--;
  dest--;

  for( ; m-- ; ){
    fscanf( fin, "%d%d", &i, &j );
    i--;
    j--;

    fscanf( fin, "%d%d", &rem[i][j], &icost[i][j] );

    adj[i].push_back( j );
    adj[j].push_back( i );
  }

  fck_it_lets_do_roy_floyd_hashtag_4_da_memez( n, src );

  total = 0;
  while( djikstra( n, src, dest ) ){
    maxadd = +INF;
    for( i = dest ; i != src ; i = prev[i] )
      maxadd = min( maxadd, rem[prev[i]][i] );

    if( maxadd > 0 ){// optimizare
      for( i = dest ; i != src ; i = prev[i] ){
        rem[prev[i]][i] -= maxadd;
        rem[i][prev[i]] += maxadd;
        total += maxadd * icost[prev[i]][i];
      }
    }
  }

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

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