Cod sursa(job #2239991)

Utilizator LucaSeriSeritan Luca LucaSeri Data 12 septembrie 2018 09:41:52
Problema Flux Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.21 kb
#include <bits/stdc++.h>


using namespace std;

const int MAXN = 105;

using Edge = pair< pair< int, int >, double >;

vector< Edge > edges;

const double eps = 1e-6;

double a[MAXN][MAXN];
double sol[MAXN];
int n, m;

bool zero(double x) {
    return (x > -eps && x < eps);
}
void gauss() {
    int m = n;

    int i, j, k;

    i = j = 1;
    while(i <= n && j <= m) {
        k = i;
        while(k <= n && zero(a[k][j])) ++k;
        if(k == n+1) {
            ++j;
            continue;
        }

        for(int x = 1; x <= m + 1; ++x) swap(a[i][x], a[k][x]);

        for(int x = m + 1; x >= j; --x) a[i][x] /= a[i][j];

        for(int ec = i + 1; ec <= n; ++ec) {
            for(int x = j + 1; x <= m + 1; ++x) a[ec][x] -= a[ec][j] * a[i][x];
            a[ec][j] = 0.0;
        }
        ++i;
        ++j;
    }

    for(i = n; i > 0; --i) {
        for(j = 1; j <= m + 1; ++j) {
            if(!zero(a[i][j])) {
                sol[j] = a[i][m + 1];
                for(k = j + 1; k <= m; ++k) sol[j] -= a[i][k]*sol[k];
                break;
            }
        }
    }
}

int tata[MAXN];
int card[MAXN];

int root(int x) {
    if(x == tata[x]) return x;
    return tata[x] = root(tata[x]);
}

void unite(int x, int y) {
    if(card[x] < card[y]) swap(x, y);
    tata[y] = tata[x];
    card[x] += card[y];
}

int main () {
    ifstream f("flux.in");
    ofstream g("flux.out");

    f >> n;
    for(int i = 1; i <= n; ++i) tata[i] = i, card[i] = 1;

    int m;
    f >> m;

    for(int i = 1; i <= m; ++i) {
        int d, b, c;
        f >> d >> b >> c;
        edges.emplace_back(make_pair(d, b), c);
        unite(root(d), root(b));
        if(d != 1) a[d][d] --, a[d][b] ++;
        if(b != 1) a[b][b] --, a[b][d] ++;
    }

    a[1][1] = 1;
    a[1][n + 1] = 0;
    a[n][n + 1] = -1;

    if(root(1) != root(n)) {
        g << "0.000\n";
        return 0;
    }

    gauss();
    double ans = 1e9;

    for(auto &x : edges) {
        if(sol[x.first.first] < sol[x.first.second])
        ans = min(ans, x.second / (sol[x.first.second] - sol[x.first.first]));
    }

    g << setprecision(3) << fixed << ans << '\n';
    return 0;
}