Cod sursa(job #831362)

Utilizator toranagahVlad Badelita toranagah Data 8 decembrie 2012 15:30:48
Problema Tunelul groazei Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.77 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <utility>
#define FORIT(it, v) for (typeof((v).begin()) it = (v).begin(); it != (v).end(); ++it)
using namespace std;
const int MAX_N = 300;
int N, M;
double matrix[MAX_N][MAX_N], r[MAX_N];
double sol;
struct neighbour { 
    int nod, cost; 
    neighbour();
    neighbour(int n, int c);
}; vector<neighbour> g[MAX_N];
void read(), solve(), print();

int main() {
    read();
    solve();
    print();
}

void read() {
    ifstream fin("tunel.in");
    fin >> N >> M;
    int n1, n2, c;
    for (int i = 1; i <= M; ++i) {
        fin >> n1 >> n2 >> c;
        g[n1].push_back(neighbour(n2, c));
        g[n2].push_back(neighbour(n1, c));
    }
    fin.close();
}

void build_matrix() {
    for (int i = 1; i < N; ++i) {
        matrix[i][i] = 1;
        double c = 1.0 / g[i].size();
        FORIT(j, g[i]) {
            matrix[i][j->nod] -= c;
            r[i] += j->cost * c;
        }
    }
    matrix[N][N] = 1;
    r[N] = 0;
}

void gauss() {
    for (int i, j = 1, k; j <= N; ++j) {
        for (i = j; i <= N; ++i) {
            if (matrix[i][j] != 0) break;
        }
        for (k = 1; k <= N; ++k) {
            swap(matrix[j][k], matrix[i][k]);
        }
        swap(r[i], r[j]);
        for (i = 1; i <= N; ++i) {
            if (i == j) continue;
            double ratio = matrix[i][j] / matrix[j][j] * -1;
            for (k = 1; k <= N; ++k) {
                matrix[i][k] += matrix[j][k] * ratio;
            }
            r[i] += r[j] * ratio;
        }
    }
}

void solve() {
    build_matrix();
    gauss();
    sol = r[1] / matrix[1][1];
}

void print () {
    ofstream fout("tunel.out");
    fout << sol;
}

neighbour::neighbour() {
    nod = cost = 0;
}
neighbour::neighbour(int n, int c) {
    nod = n;
    cost = c;
}