Cod sursa(job #2671866)

Utilizator NicolaalexandraNicola Alexandra Mihaela Nicolaalexandra Data 12 noiembrie 2020 19:21:10
Problema Flux Scor 60
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.58 kb
#include <bits/stdc++.h>
#define DIM 110
#define INF 2000000000
#define EPS 0.0001
using namespace std;

long double a[DIM][DIM],sol[DIM],mini;
vector <pair<int,int> > L[DIM],inv[DIM];
int g_ext[DIM],g_int[DIM],viz[DIM];
int n,nr,i,j,k,t,x,y,cost;

long double modul (long double n){
    return max (n,-n);
}

int f (long double n){
    if (n >= -EPS && n <= EPS)
        return 1;
    return 0;
}

void dfs (int nod){
    viz[nod] = 1;
    for (auto it : L[nod]){
        int vecin = it.first;
        if (vecin == n)
            continue;
        long double flux = modul (sol[vecin] - sol[nod]);

        if (!f(flux))
            mini = min (mini,(long double)it.second / flux);

        if (!viz[vecin])
            dfs (vecin);
    }
}

int main (){

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

    cin>>n>>nr;
    for (i=1;i<=nr;i++){
        cin>>x>>y>>cost;
        L[x].push_back(make_pair(y,cost));
        L[y].push_back(make_pair(x,cost));

        /// x y
        if (x != 1 && x != n){
            a[x][x]++;
            a[x][y]--;
        }

        /// y x
        if (y != 1 && y != n){
            a[y][y]++;
            a[y][x]--;
        }
    }
    a[1][1] = a[n][n] = a[n][n+1] = 1;


   /* for (i=1;i<=n;i++,cout<<endl)
        for (j=1;j<=n+1;j++)
            cout<<a[i][j]<<" ";
   */

    /// gauss

    i = j = 1;

    while (i <= n && j <= n){

        int l = i;
        while (l <= n && !a[l][j])
            l++;

        if (l == n+1){
            j++;
            continue;
        }

        if (l != i){
            for (k=1;k<=n+1;k++)
                swap (a[i][k],a[l][k]);
        }

        /// impart ecuatia prin coef la care sunt

        for (k=j+1;k<=n+1;k++)
            a[i][k] /= a[i][j];
        a[i][j] = 1;

        for (k=i+1;k<=n;k++){
            for (t=j+1;t<=n+1;t++)
                a[k][t] -= a[i][t] * a[k][j];
            a[k][j] = 0;
        }

        i++, j++;
    }

    /// sol[i] = suma fluxurilor de la sursa la i

    for (i=n;i;i--){
        int j = 1;
        while (j <= n+1 && f(a[i][j]))
            j++;
        if (j > n+1)
            continue;

        sol[j] = a[i][n+1];
        for (k=j+1;k<=n+1;k++)
            sol[j] -= sol[k] * a[i][k];

    }

    mini = INF*1.0;
    dfs (1);

    if (mini == INF){
        cout<<0;
        return 0;
    }

    long double ans = 0;
    for (auto it : L[n])
        ans += modul(sol[n] - sol[it.first]) * mini;

    cout<<setprecision(5)<<fixed<<ans;

    return 0;
}