Cod sursa(job #106582)

Utilizator astronomyAirinei Adrian astronomy Data 18 noiembrie 2007 19:26:54
Problema Tunelul groazei Scor Ascuns
Compilator cpp Status done
Runda Marime 1.81 kb
#include <cstdio>
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <vector>
using namespace std;

#define MAXN 301
#define mp make_pair
#define pb push_back

double E[MAXN][MAXN];
double X[MAXN];
int N, M;
vector< pair<int,int> > G[MAXN];

char GG[MAXN][MAXN], viz[MAXN];

void dfs(int x)
{
    for(int y = 1; y <= N; y++)
     if(!viz[y] && GG[x][y])
        viz[y] = 1, dfs(y);
}

void solve(void)
{
    int i, j, k;
    double coef, val;

    for(i = 1; i < N; i++)
    {
        for(j = i+1; j < N; j++)
         for(coef = -E[j][i]/E[i][i], k = i; k <= N; k++)
            E[j][k] += coef*E[i][k];
    }
    for(i = N-1; i >= 1; i--)
    {
        for(val = E[i][N], j = i+1; j < N; j++)
            val = val - E[i][j]*X[j];
        X[i] = val / E[i][i];
    }
}

void read_data(void)
{
    int i, j, k, a, b, c;
    
    scanf("%d %d\n", &N, &M);

    assert(N >= 1 && M <= 100000 && M >= N-1);

    for(i = 1; i <= M; i++)
        scanf("%d %d %d\n", &a, &b, &c),
        G[a].pb(mp(b,c)), G[b].pb(mp(a,c)), GG[a][b] = GG[b][a] = 1,
        assert(a != b),
        assert(a >= 1 && a <= N),
        assert(b >= 1 && b <= N),
        assert(c <= 10000);

    for(i = 1; i < N; i++)
    {
        for(E[i][i] = -1.0, j = 0; j < G[i].size(); j++)
        {
            if(G[i][j].first != N)
                E[i][ G[i][j].first ] += 1.0/G[i].size();
            E[i][N] -= 1.0/G[i].size()*G[i][j].second;
        }
    }
}

void write_data(void)
{
    printf("%.3lf\n", X[1]);
}

int main(void)
{
    assert(freopen("tunel.in", "rt", stdin));
    freopen("tunel.out", "wt", stdout);

    read_data();
    solve();
    write_data();

    viz[1] = 1, dfs(1);
    for(int i = 1; i <= N; i++)
        assert(viz[i]);

    return 0;
}