Cod sursa(job #1093868)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 28 ianuarie 2014 18:30:51
Problema Tunelul groazei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.52 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <iomanip>

using namespace std;

const int Nmax = 260;
const long double EPS = 1e-4;

vector < pair<int,int> > G[Nmax];
long double A[Nmax][Nmax], SOL[Nmax];

int N, M;

void create_gauss()
{
    for ( int i = 1; i <= N; ++i )
    {
        A[i][i] = -1.0;

        if ( i == N ) continue;

        int grad = G[i].size(), sumdist = 0;

        for ( auto x: G[i] )
        {
            sumdist += x.second;
            A[i][x.first] += 1.0 / grad;
        }

        A[i][N + 1] -= 1.0 * sumdist / grad;
    }
}

void GaussianElimination()
{
    int i = 1, j = 1;

    while ( i <= N && j <= N )
    {
        int x = 0;

        for ( int k = i; k <= N; ++k )
        {
            if ( A[k][j] > EPS || A[k][j] < -EPS )
            {
                x = k;
                break;
            }
        }

        if ( x == 0 )
        {
            j++;
            continue;
        }

        if ( x != i )
        {
            for ( int k = 1; j <= N + 1; ++j )
            {
                swap( A[x][k], A[i][k] );
            }
        }

        for ( int k = j + 1; k <= N + 1; ++k )
                A[i][k] /= A[i][j];

        A[i][j] = 1;

        for ( int l = i + 1; l <= N; ++l )
        {
            for ( int c = j + 1; c <= N + 1; ++c )
            {
                A[l][c] -= A[i][c] * A[l][j];
            }

            A[l][j] = 0;
        }

        i++;
        j++;
    }
}

void compute_values()
{
    for ( int i = N; i >= 1; i-- )
            for ( int j = 1; j <= N + 1; ++j )
            {
                if ( A[i][j] > EPS || A[i][j] < -EPS )
                {
                    if ( j == N + 1 )
                    {
                        cout << "Error";
                        return;
                    }

                    SOL[j] = A[i][N + 1];

                    for ( int k = j + 1; k <= N; ++k )
                            SOL[j] -= SOL[k] * A[i][k];

                    break;
                }
            }
}

int main()
{
    ifstream f("tunel.in");
    ofstream g("tunel.out");

    f >> N >> M;

    for ( int i = 1, a, b, c; i <= M; ++i )
    {
        f >> a >> b >> c;

        G[a].push_back( make_pair( b, c ) );
        G[b].push_back( make_pair( a, c ) );
    }

    create_gauss();
    GaussianElimination();
    compute_values();

    g << fixed << setprecision( 4 ) << SOL[1] << "\n";

    return 0;
}