Cod sursa(job #2952750)

Utilizator andrei_marciucMarciuc Andrei andrei_marciuc Data 9 decembrie 2022 20:50:52
Problema Tunelul groazei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.41 kb
#include <fstream>
#include <iomanip>
#include <vector>
using namespace std;
 
ifstream cin( "tunel.in" );
ofstream cout( "tunel.out" );
 
struct Andrei {
    int nod, cost;
};

const double EPS = 1e-6;
const int MAX = 257;

vector<Andrei> noduri[ MAX ];
double ecuati[ MAX ][ MAX ];
double sol[ MAX ];
int n, m;
 
bool isZero( double x ) {
    return ( x < -EPS || x > EPS );
}
 
void gauss( double ecuati[ MAX ][ MAX ], double sol[ MAX ], int n, int m ) {
    int i = 1, j = 1;
    while( i <= n && j <= m ) {
        int k = i;
        while( k <= n ) {
            if( isZero( ecuati[ k ][ j ] ) )
                break;
            k++;
        }
 
        if( k == n + 1 ) {
            j++;
            continue;
        }
 
        if( k != i )
            for( int jj = 1; jj <= m + 1; jj++ )
                swap( ecuati[ k ][ jj ], ecuati[ i ][ jj ] );
        
        for( int jj = m + 1; jj >= j; jj-- )
            ecuati[ i ][ jj ] /= ecuati[ i ][ j ];
 
        for( int ind = i + 1; ind <= n; ind++ )
            for( int jj = m + 1; jj >= j; jj-- )
                ecuati[ ind ][ jj ] -= ecuati[ ind ][ j ] * ecuati[ i ][ jj ];
        i++, j++;
    }
 
    for( int i = n; i >= 1; i-- )
        for( int j = 1; j <= m + 1; j++ ) 
            if( isZero( ecuati[ i ][ j ] ) ) {
                if( j == m + 1 )
                    exit( 0 ); 
 
                sol[ j ] = ecuati[ i ][ m + 1 ];
                for( int jj = j + 1; jj <= m; jj++ )
                    sol[ j ] -= sol[ jj ] * ecuati[ i ][ jj ];
                break;
            }
}
 
int main()
{ 
    /*read*/{
        cin >> n >> m;
        
        int x, y, cost;
        for(int i = 1; i <= m; i++) {
            cin >> x >> y >> cost;
            noduri[ x ].push_back( { y, cost } );
            noduri[ y ].push_back( { x, cost } );
        }
    }
 
    /*make ecuati*/{
        for( int i = 1; i <= n - 1; i++ ) {
            double suma = 0;
     
            double val = 1 / (double)noduri[ i ].size();
            for( const Andrei& nod : noduri[ i ] ) {
                ecuati[ i ][ nod.nod ] += val;
                suma += nod.cost;
            }
     
            ecuati[ i ][ n + 1 ] = ( -suma / (double)noduri[ i ].size() );
            ecuati[ i ][ i ] = -1;
            ecuati[ i ][ n ] = 0;
        }
    }
 
    gauss( ecuati, sol, n, n );
 
    /*read*/{
        cout << fixed << setprecision(7);
        cout << sol[ 1 ] << '\n';
    }
    return 0;
}