Cod sursa(job #2893775)

Utilizator mircea_007Mircea Rebengiuc mircea_007 Data 26 aprilie 2022 17:30:32
Problema Tunelul groazei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.08 kb
// This program was written on 26.04.2022
// for problem tunel
// by Mircea Rebengiuc

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

#include <valarray>

#define MAXN 255
#define MAXEQ (MAXN + 1)

#define EPS 1e-7
#define NIL -1

std::valarray<double> e[MAXEQ];
int grad[MAXN];

static inline bool null( const double &t ){
  return std::abs( t ) <= EPS;
}

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( "tunel.in",  "r" );
  fout = fopen( "tunel.out", "w" );
  
  int n, m, neq, i, j, k, a, b, w;

  n = fgetint();
  neq = n + 1;

  for( i = 0 ; i < neq ; i++ )
    e[i].resize( n + 1 );

  for( m = fgetint() ; m-- ; ){
    a = fgetint() - 1;
    b = fgetint() - 1;
    w = fgetint();
    
    grad[a]++;
    grad[b]++;
    
    e[a][b]++;
    e[b][a]++;
    
    e[a][n] += w;
    e[b][n] += w;
  }

  for( i = 0 ; i < n ; i++ ){
    for( j = 0 ; j <= n ; j++ )
      e[i][j] /= grad[i];
    e[i][i] = -1;
  }
  
  e[n][0] = 1;
  for( i = 1 ; i <= n ; i++ )
    e[n][i] = 0;
  
  /*
  for( i = 0 ; i < neq ; i++ ){
    for( j = 0 ; j < n ; j++ )
      printf( " %lf", e[i][j] );
    printf( " | %lf\n", e[i][n] );
  }*/
  
  // aplicam eliminarea gausiana
  for( i = j = 0 ; i < neq && j < n ; j++ ){
    if( null( e[i][j] ) ){// nu avem variabila 'dominanta'
      // gasim alta ecuatie cu coeficient nenul
      k = i + 1;
      while( k < neq && null( e[k][j] ) )
        k++;
      
      if( k < neq ){
        std::swap( e[i], e[k] );// O(1)
      }
    }
    
    if( !null( e[i][j] ) ){
      // facem toti coeficientii de la variabila j nuli
      for( k = 0 ; k < neq ; k++ )
        if( k != i && !null( e[k][j] ) )
          e[k] -= e[i] * (e[k][j] / e[i][j]);
      
      i++;
    }
  }
  
  /*
  for( i = 0 ; i < neq ; i++ ){
    for( j = 0 ; j < n ; j++ )
      printf( " %lf", e[i][j] );
    printf( " | %lf\n", e[i][n] );
  }*/

  fprintf( fout, "%lf\n", e[n - 1][n] / e[n - 1][n - 1] );
  
  fclose( fin );
  fclose( fout );
  return 0;
}