Cod sursa(job #1833678)

Utilizator depevladVlad Dumitru-Popescu depevlad Data 22 decembrie 2016 21:50:57
Problema Flux Scor 64
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.83 kb
#include <bits/stdc++.h>

using namespace std;

const int NMAX = 105;
const int INF = numeric_limits <int> :: max() / 2;
const double EPS = 1e-10;

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

int n;
int m;
double gauss[NMAX][NMAX];

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];
        }
    }
}

int edges_c[NMAX][NMAX];
int edges_n[NMAX][NMAX];

int main() {
    f >> n >> m;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            edges_c[i][j] = INF;
        }
    }
    for (int i = 1; i <= m; i++) {
        int u, v, c;
        f >> u >> v >> c;
        edges_c[u][v] = min(edges_c[u][v], c);
        edges_c[v][u] = min(edges_c[u][v], c);
        edges_n[u][v]++;
        edges_n[v][u]++;
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            if (edges_c[i][j] == INF) {
                edges_c[i][j] = 0;
            }
        }
    }

    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            if (edges_n[i][j] > 0) {
                gauss[j][j] += edges_n[i][j];
                gauss[j][i] -= edges_n[i][j];
            }
        }
    }
    for (int i = 1; i <= n; i++) {
        gauss[i][n + 1] = 0.0;
        gauss[i][1] = 0.0;
        gauss[1][i] = 0.0;
    }
    gauss[1][n + 1] = 0.0;
    gauss[n][n + 1] = 1.0;

    rowEchelon();
    Solve();

    double sol = 1e20;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            double f = (sys_sol[j] - sys_sol[i]);
            if (edges_c[i][j] > 0 && f > EPS) {
                sol = min(sol, edges_c[i][j] / f);
            }
        }
    }

    g << sol << "\n";
    return 0;
}