Cod sursa(job #1178968)

Utilizator danalex97Dan H Alexandru danalex97 Data 27 aprilie 2014 16:48:09
Problema Flux Scor 12
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.96 kb
#include <fstream>
#include <iostream>
#include <iomanip>
#include <cstdlib>
using namespace std;

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

const double eps = 1e-9;
const int N = 110;
const int infi = 1<<20;

int n,m,capacity[N][N],edges[N][N],mark[N];
double a[N][N],x[N];

void df(int x)
{
    mark[x] = 1;
    for (int y=1;y<=n;++y)
        if ( edges[x][y] && mark[y] == 0 )
            df(y);
}

/**

Observatia de baza e ca conditia din enunt e echivalent cu toate drumurile de la 1 la i sunt constante.
Aceasta conditie poate fi formulata sub forma unui sistem de ecuatii in care necunoscutele vor fi
X[i] - suma fluxurilor de la 1 la i. X[0] = 0 , X[n] = cap.

*/

void gauss()
{
    int i = 1 , j = 1;
    while ( i < n && j < n )
    {
        int now = -1;
        for (int k=i;i<n;++k)
            if ( eps < max(a[k][j],-a[k][j]) )
            {
                now = k;
                break;
            }
        if ( now == -1 )
        {
            ++j;
            continue;
        }

        for (int k=1;k<=n;++k) swap(a[i][k],a[now][k]);
        for (int k=n;k>=j;--k) a[i][k] /= a[i][j];

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

        ++i;
        ++j;
    }

    for (int i=n-1;i>0;--i)
        for (int j=1;j<=n;++j)
            if ( eps <= max(-a[i][j],a[i][j]) )
            {
                if ( j == n )
                {
                    //G<<0<<'\n';
                    exit(0);
                }
                x[j] = a[i][n];

                for (int k=i-1;k>0;--k)
                {
                    a[k][n] -= x[j] * a[k][j];
                    a[k][j] = 0;
                }

                break;
            }
}

int main()
{
    F>>n>>m;
    for (int i=1,a,b,c;i<=m;++i)
    {
        F>>a>>b>>c;
        edges[a][b]++;
        edges[b][a]++;
        if ( edges[a][b] == 1 )
            capacity[a][b] = capacity[b][a] = c;
        else
        {
            capacity[a][b] = min(capacity[a][b],c);
            capacity[b][a] = capacity[a][b];
        }
    }

    G<<"0\n";
    return 0;

    df(1);
    if ( mark[n] == 0 )
    {
        G<<0<<'\n';
        return 0;
    }

    for (int i=2;i<=n;++i)
        for (int j=1;j<=n;++j)
            if ( i != j )
            {
                a[i-1][i-1] += edges[i][j];
                if ( j != 1 ) a[i-1][j-1] -= edges[i][j];
            }
    a[n-1][n] = 1;

    gauss();

    double ans = infi;
    for (int i=1;i<=n;++i)
        for (int j=1;j<=n;++j)
            if ( edges[i][j] )
                ans = min(ans, double(capacity[i][j]) / max(x[j-1]-x[i-1],x[i-1]-x[j-1]) );

    if ( max(ans-double(infi),double(infi)-ans) <= eps )
        G<<0<<'\n';
    else
        G<<fixed<<setprecision(4)<<ans<<'\n';
}