Cod sursa(job #1684576)

Utilizator SmarandaMaria Pandele Smaranda Data 11 aprilie 2016 10:15:12
Problema Tunelul groazei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.21 kb
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>

using namespace std;

const int N = 300;
const double eps = 1.e-14;

int  nr [N][N], grad [N];
vector <int> costuri [N];
double A [N][N], ans [N], aux [N];
int n;

void gauss () {
    int i, j, x, y;
    double z, s;

    i = 1; j = 1;
    while (i <= n && j <= n) {
        for (x = i; x <= n; x ++)
            if (A [x][j] < -eps || A [x][j] > eps)
                break;
        if (fabs (A [x][j]) < eps) { //variabila libera
            j ++;
            continue;
        }
        if (i != x) {
            memcpy (aux, A [i], sizeof (A [i]));
            memcpy (A [i], A [x], sizeof (A [x]));
            memcpy (A [x], aux, sizeof (aux));
        }
        z = A [i][j];
        for (y = j; y <= n + 1; y ++)
            A [i][y] = A [i][y] / z;
        for (x = i + 1; x <= n; x ++) {
            z = A [x][j];
            for (y = j; y <= n + 1; y ++)
                A [x][y] = A [x][y] - z * A [i][y];
        }
        ++ i; ++ j;
    }

    for (i = n; i >= 1; i --) {
        x = -1;
        s = 0;
        for (j = 1; j <= n + 1; j ++) {
            if (A [i][j] > eps || A [i][j] < -eps) {
                s = 0;
                for (y = j + 1; y <= n; y ++)
                    s = s + ans [y] * A [i][y];
                ans [j] = A [i][n + 1] - s;
                break;
            }
        }
    }
}

int main () {
    int m, i, x, y, c, j;

    freopen ("tunel.in", "r", stdin);
    freopen ("tunel.out", "w", stdout);

    scanf ("%d%d", &n, &m);
    for (i = 1; i <= m; i ++) {
        scanf ("%d%d%d", &x, &y, &c);
        costuri [x].push_back (c);
        costuri [y].push_back (c);
        nr [x][y] ++;
        nr [y][x] ++;
        grad [x] ++; grad [y] ++;
    }
    for (i = 1; i <= n; i ++) {
        for (j = 1; j < n; j ++)
            if (i != j)
                A [i][j] = -1.0 * nr [i][j] / grad [i];
        A [i][i] = 1;
        if (i == n)
            A [n][n] = 0;
        for (j = 0; j < costuri [i].size (); ++ j)
            A [i][n + 1] = A [i][n + 1] + 1.0 * costuri [i][j] / grad [i];
    }
    gauss ();
    printf ("%f\n", ans [1]);
    return 0;
}