Cod sursa(job #1652157)

Utilizator felixiPuscasu Felix felixi Data 14 martie 2016 18:51:30
Problema Flux Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.31 kb
#include <cassert>
#include <cmath>

#include <algorithm>
#include <fstream>
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
using namespace std;

#define int64 long long

const int inf = 0x3f3f3f3f, kMaxN = 205;
const double eps = 0.000000001;

ifstream in("flux.in");
ofstream out("flux.out");

double gauss[kMaxN][kMaxN];
double rezN[kMaxN];

double min(double a, double b) {
    if (a > b)
        return b;
    return a;
}

bool equal(double a, double b) {
    if (-eps <= a - b and a - b <= eps)
        return true;
    return false;
}

vector<pair<int, int> > vertex[kMaxN];

int main() {
    int n, m; in >> n >> m;
    while (m--) {
        int a, b, c; in >> a >> b >> c;
        vertex[a].push_back(make_pair(b, c));
        vertex[b].push_back(make_pair(a, c));

        gauss[b][b] += 1.0;
        gauss[b][a] -= 1.0;

        gauss[a][a] += 1.0;
        gauss[a][b] -= 1.0;

        gauss[a][1] = gauss[b][1] = 0.0;
    }

    for (int l = 2; l < n; ++l) {
        if (equal(gauss[l][l], 0.0))
            continue;
        double ratio = gauss[l][l];
        for (int c = 2; c <= n; ++c) {
            gauss[l][c] /= ratio;
        }
    }

    for (int l = 2; l < n; ++l) {
        if (vertex[l].size() == 0)
            continue;

        for (int lp = 2; lp < n; ++lp) {
            if (lp == l)
                continue;
            if (not equal(gauss[lp][l], 0.0)) {
                double ratio = -1.0 * gauss[lp][l] / gauss[l][l];
                for (int c = 1; c <= n; ++c) {
                    gauss[lp][c] += ratio * gauss[l][c];
                }
            }
        }
    }

    for (int i = 2; i <= n; ++i) {
        if (equal(gauss[i][i], 0.0)) {
            rezN[i] = 0.0;
        } else {
            rezN[i] = gauss[i][n] / gauss[i][i];
        }
        rezN[i] = fabs(rezN[i]);
    }

    double flow = 0.0;
    for (auto itr : vertex[n]) {
        flow += 1.0;
        flow -= rezN[itr.first];
    }

    double mn = 1.0 * inf;

    for (int i = 2; i <= n; ++i) {
        for (auto itr : vertex[i]) {
            double current = fabs(rezN[i] - rezN[itr.first]);
            mn = min(mn, itr.second / current);
        }
    }

    out << fixed << setprecision(9) << mn * flow;
    return 0;
}