Cod sursa(job #110277)

Utilizator dominoMircea Pasoi domino Data 26 noiembrie 2007 02:42:17
Problema Tunelul groazei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.77 kb
#include <stdio.h>
#include <algorithm>
#include <vector>

using namespace std;

#define MAX_N 260
#define FIN "tunel.in"
#define FOUT "tunel.out"
#define pb push_back
#define mp make_pair
#define f first
#define s second
#define abs(x) ((x) < 0 ? -(x) : (x))
#define EPS 1e-5

int N, M, pos[MAX_N];
double eq[MAX_N][MAX_N], var[MAX_N];
vector< pair<int, int> > G[MAX_N];

int main(void)
{
    int i, j, k, p, max_pos;
    double t;
    vector< pair<int, int> >::iterator it;

    freopen(FIN, "r", stdin);
    freopen(FOUT, "w", stdout);

    for (scanf("%d %d", &N, &M); M; --M)
    {
        scanf("%d %d %d", &i, &j, &k);
        --i, --j;
        G[i].pb(mp(j, k));
        G[j].pb(mp(i, k));
    }

    for (i = 0; i+1 < N; ++i)
    {
        eq[i][i] = -1.0;
        for (it = G[i].begin(); it != G[i].end(); ++it)
        {
            eq[i][it->f] += 1.0/G[i].size();
            eq[i][N] -= (double)it->s/G[i].size();
        }
    }

    for (p = k = 0; k+1 < N; ++k)
    {
        max_pos = p;
        for (i = p; i+1 < N; ++i)
            if (abs(eq[max_pos][k]) < abs(eq[i][k]))
                max_pos = i;
        if (abs(eq[max_pos][k]) < EPS) { pos[k] = -1; continue; }
        for (i = 0; i <= N; ++i)
            swap(eq[p][i], eq[max_pos][i]);
        for (i = p+1; i+1 < N; ++i)
        {
            t = eq[i][k]/eq[p][k];
            for (j = 0; j <= N; ++j)
                eq[i][j] -= t*eq[p][j];
        }
        pos[k] = p++;
    }

    for (k = N-2; k >= 0; --k)
    {
        if (pos[k] == -1) { var[k] = 0.0; continue; }
        t = eq[pos[k]][N];
        for (i = k+1; i < N; ++i)
            t -= eq[pos[k]][i]*var[i];
        var[k] = t/eq[pos[k]][k];
    }
    printf("%.4f\n", var[0]);

    return 0;
}