Cod sursa(job #323477)

Utilizator wefgefAndrei Grigorean wefgef Data 12 iunie 2009 11:25:56
Problema Tunelul groazei Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.74 kb
#include <stdio.h>
#include <vector>

using namespace std;

#define MAX_N 256
#define pb push_back

int n, m, i, j;
double mat[MAX_N][MAX_N];
vector <int> V[MAX_N], C[MAX_N];

void cit() {
    freopen("tunel.in", "r", stdin);
    freopen("tunel.out", "w", stdout);
    
    scanf("%d %d", &n, &m);
    for (i = 1; i <= m; i++) {
        int a = 0, b = 0, c = 0;
        scanf("%d %d %d", &a, &b, &c);
        
        V[a].pb(b); V[b].pb(a);
        C[a].pb(c); C[b].pb(c);
    }
}

void inter(int l1, int l2) {
    for (int i = 1; i <= n + 1; i++) {
        double aux = mat[l1][i];
        mat[l1][i] = mat[l2][i];
        mat[l2][i] = aux;
    }
}

void scad(int l1, int l2, double val) {
    for (int i = 1; i <= n + 1; i++) 
        mat[l1][i] += mat[l2][i] * val;
}

void gauss() {
    for (i = 1; i < n; i++) {
        for (j = i; j <= n; j++)
            if (mat[j][i] != 0) {
                inter(i, j);
                break;
            }
            
        for (j = 1; j <= n; j++)
            if (j != i && mat[j][i] != 0)
                scad(j, i, -mat[j][i] / mat[i][i]);

    }

}

void solve() {
    for (i = 1; i < n; i++) {
        int len = V[i].size();
        double sum = 0;
        for (j = 0; j < len; j++) {
            //o sa am -1/grad pentru toti vecinii, 0 unde nu e vecin si 1 pentru i
            mat[i][V[i][j]] = -1.0/len;
            sum += C[i][j];
        }
        
        mat[i][i] = 1;
        
        //in dreapta am suma(costuri muchii) / grad
        mat[i][n + 1] = (double(sum)) / len;
    }
    
    mat[n][n] = 1;
        
    gauss();
    
    printf("%lf\n", mat[1][n + 1] / mat[1][1]);
}

int main() {

    cit();
    solve();

    return 0;
}