Cod sursa(job #2003898)

Utilizator akaprosAna Kapros akapros Data 24 iulie 2017 12:50:30
Problema Flux Scor 96
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.87 kb
#include <bits/stdc++.h>
#define maxN 102
#define maxM 5002
#define e 1e-9
#define inf 1e30
using namespace std;

FILE *fin = freopen("flux.in", "r", stdin);
FILE *fout = freopen("flux.out", "w", stdout);

/* --------------------------------------------- */
int n, m;
int C[maxN][maxN], G[maxN][maxN];
/* --------------------------------------------- */
double X[maxN], a[maxN][maxN];
/* --------------------------------------------- */
double mul, ans;

/* ------------------------- Gauss ------------------------- */
void Gauss()
{
    int i = 1, j = 1;
    while (i <= n && j <= n)
    {
        int x, y;
        for (x = i; x <= n; ++ x)
            if (a[x][j] > e || a[x][j] < -e)
                break;
        if (x == n + 1)
        {
            ++ j;
            continue;
        }
        if (x != i)
            for (y = 1; y <= n + 1; ++ y)
                swap(a[x][y], a[i][y]);

        for (y = j + 1; y <= n + 1; ++ y)
            a[i][y] = (double)(a[i][y] / a[i][j]);
        a[i][j] = 1.00000000000;

        for (y = i + 1; y <= n; ++ y)
        {
            int c;

            for (c = j + 1; c <= n + 1; ++ c)
                a[y][c] -= a[y][j] * a[i][c];
            a[y][j] = 0.0000000000;
        }
        ++ i;
        ++ j;
    }
}
void Coef()
{
    int i, j, x;
    for (i = n; i >= 1; -- i)
        for (j = 1; j <= n + 1; ++ j)
            if (a[i][j] > e || a[i][j] < -e)
            {
                if (j == n + 1)
                {
                    X[n + 1] = 0;
                    return ;
                }
                X[j] = a[i][n + 1];
                for (x = j + 1; x <= n; ++ x)
                    X[j] -= a[i][x] * X[x];
                break;
            }
}
/* --------------------------------------------- */
void findMinC()
{
    mul = inf;
    for (int i = 0; i < n; ++ i)
        for (int j = i + 1; j <= n; ++ j)
            if (G[i][j])
            {
                double flowij = abs(X[j] - X[i]),
                       c = (double)C[i][j] / flowij;
                mul = min(mul, c);
            }
}
int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= m; ++ i)
    {
        int x, y, c;
        scanf("%d%d%d", &x, &y, &c);
        -- x;
        -- y;

        C[y][x] = C[x][y] = (!a[x][y] ? c : min(c, C[x][y]));
        ++ a[x][y]; ++ G[x][y];
        ++ a[y][x]; ++ G[y][x];
        -- a[x][x];
        -- a[y][y];
    }
    X[n - 1] = 1.0;
    X[0] = 0;
    -- n;
    for (int i = 1; i < n; ++ i)
    {
        a[i][0] = 0;
        a[i][n] *= -X[n];
    }
    -- n;
    Gauss();
    Coef();
    ++ n;
    findMinC();
    for (int i = 0; i < n; ++ i)
        if (G[i][n])
            ans += mul * abs(X[n] - X[i]) * G[i][n];
    if (X[n] == 0)
        printf("0.0\n");
    else
        printf("%.9lf\n", ans);
    return 0;
}