Cod sursa(job #1519800)

Utilizator lflorin29Florin Laiu lflorin29 Data 7 noiembrie 2015 20:56:30
Problema Tunelul groazei Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.82 kb
#include <bits/stdc++.h>

using namespace std;

const double eps = 1e-10;

bool HHp(double val) {
    return abs(val) > eps;
}

double gauss(vector<vector<double>>&A, int N) {
    for(int i = 1, j = 1; i <= N && j <= N;) {
        int res = -1;
        for(int k = i; k <= N && res == -1; ++k)
            if(HHp(A[k][j]))
               res = k;
        if(res == -1) {
            ++j;
            continue;
        }
        swap(A[res], A[i]);

        for(int nc = j + 1 ; nc <= N + 1; ++nc)
            A[i][nc] /= A[i][j];
        A[i][j] = 1;

        for(int nl = i + 1; nl <= N; ++nl) {
            for(int nc = j + 1; nc <= N + 1; ++nc)
                A[nl][nc] -= A[i][nc] * A[nl][j];
            A[nl][j] = 0;
        }
        ++i; ++j;
    }
    vector<int>ans(N + 1);

    for(int i = N; i; --i)
      for(int j = 1 ; j <= N; ++j)
          if(HHp(A[i][j])) {
            ans[j] = A[i][N + 1];
            for(int l = j + 1; l <= N; ++l)
                ans[j] -= A[i][l] * ans[l];
            break;
          }
    return ans[1];
}
int main() {
    ifstream cin("tunel.in");
    ofstream cout("tunel.out");

    int N, M; cin >> N >> M;
    vector<vector<double>>A(N + 1, vector<double>(N + 2));
    vector<vector<pair<int,int>>>edg(N + 1);
    while(M--) {
        int fr, to, val;
        cin >> fr >> to >> val;
        edg[fr].emplace_back(to, val);
        edg[to].emplace_back(fr, val);
    }

    for(int i = 1; i < N; ++i) {
        int mmr = (int)edg[i].size();
        double ret = 0;
        for(auto it : edg[i]) {
           A[i][it.first] += -1.0 / mmr;
           ret += it.second;
        }
        A[i][i] = 1;
        A[i][N + 1] = ret / mmr;
    }

    A[N][N] = 1;
    cout << fixed << setprecision(10);
    cout << gauss(A, N);
    return 0;
}