Cod sursa(job #1833612)

Utilizator depevladVlad Dumitru-Popescu depevlad Data 22 decembrie 2016 20:00:20
Problema Flux Scor 68
Compilator cpp Status done
Runda Lista lui wefgef Marime 2.62 kb
#include <bits/stdc++.h>

using namespace std;

const int NMAX = 105;
const int MMAX = 5005;
const double EPS = 1e-10;

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

int n;
int m;
int fi[MMAX];
int se[MMAX];
int cap[MMAX];
double gauss[NMAX][NMAX];

inline void addEdge(int u, int v) {
    gauss[u][u]++;
    gauss[u][v]--;
    gauss[v][v]++;
    gauss[v][u]--;
}

inline void swapLines(int i, int j) {
    for (int k = 1; k <= n + 1; k++) {
        swap(gauss[i][k], gauss[j][k]);
    }
}

inline void scaleAdd(int i, int j, double c) {
    for (int k = 1; k <= n + 1; k++) {
        gauss[j][k] += gauss[i][k] * c;
    }
}

void rowEchelon() {
    int i = 1;
    int j = 1;
    while (i <= n && j <= n) {
        int ln_max = i;
        for (int k = i + 1; k <= n; k++) {
            if (gauss[ln_max][j] < gauss[k][j]) {
                ln_max = k;
            }
        }
        if (fabs(gauss[ln_max][j]) > EPS) {
            swapLines(ln_max, i);
            for (int k = i + 1; k <= n; k++) {
                double c = (gauss[k][j] / gauss[i][j]) * (-1);
                scaleAdd(i, k, c);
            }
            i++;
        }
        else {
            j++;
        }
    }
}

double sys_sol[NMAX];

void Solve() {
    for (int i = n; i >= 1; i--) {
        int j = 1;
        while (j <= n && fabs(gauss[i][j]) < EPS) {
            j++;
        }
        if (j <= n) {
            for (int k = j + 1; k <= n; k++) {
                if (fabs(gauss[i][k]) > EPS) {
                    gauss[i][n + 1] -= gauss[i][k] * sys_sol[k];
                }
            }
            sys_sol[j] = gauss[i][n + 1] / gauss[i][j];
        }
    }
}

double scaleSystem() {
    double c = 1e20;
    for (int i = 1; i <= m; i++) {
        double flow = fabs(sys_sol[se[i]] - sys_sol[fi[i]]);
        if (flow > EPS) {
            c = min(c, cap[i] / flow);
        }
    }
    return c;
}

int main() {
    f >> n >> m;
    for (int i = 1; i <= m; i++) {
        f >> fi[i] >> se[i] >> cap[i];
        addEdge(fi[i], se[i]);
    }
    gauss[1][n + 1] = 1.0;
    gauss[n][n + 1] = 1.0;
//    for (int i = 1; i <= n; i++) {
//        for (int j = 1; j <= n; j++) {
//            cerr << gauss[i][j] << " ";
//        }
//        cerr << " | " << gauss[i][n + 1] << "\n";
//    }
//    cerr << "\n";
    rowEchelon();
    Solve();
//    for (int i = 1; i <= n; i++) {
//        for (int j = 1; j <= n; j++) {
//            cerr << gauss[i][j] << " ";
//        }
//        cerr << " | " << gauss[i][n + 1] << "\n";
//    }
//    cerr << "\n";
//    for (int i = 1; i <= n; i++) {
//        g << sys_sol[i] << " ";
//    }
//    g << "\n";
    g << scaleSystem() << "\n";
    return 0;
}