Cod sursa(job #1086669)

Utilizator tzipleatudTudor Tiplea tzipleatud Data 18 ianuarie 2014 14:10:12
Problema Flux Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.03 kb
#include <fstream>
#include <algorithm>
#include <iomanip>
#include <cstdlib>
#define NM 110
#define EPS 1e-9
#define INF 10000.0*100000.0

using namespace std;

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

int N, M;
double ANS=INF;
int Cap[NM][NM], CountE[NM][NM];
double Gauss[NM][NM], Sol[NM];
bool foundsol=1;
bool Visited[NM];

inline double myabs (double x)
{
    return (x<0?-x:x);
}

void Read ()
{
    f >> N >> M;
    for (int i=1; i<=M; i++)
    {
        int a, b, c;

        f >> a >> b >> c;

        CountE[a][b]++;
        CountE[b][a]++;

        if (CountE[a][b]==1)
        {
            Cap[a][b]=c;
            Cap[b][a]=c;
        }
        else
        {
            Cap[a][b]=min(Cap[a][b], c);
            Cap[b][a]=min(Cap[b][a], c);
        }
    }

    f.close();
}

void Print (double ANS)
{
    g << fixed << setprecision(10) << ANS << '\n';
    g.close();

    exit(0);
}

void DF (int node)
{
    Visited[node]=1;
    for (int it=1; it<=N; it++)
        if (CountE[node][it]!=0 && !Visited[it])
            DF(it);
}

void BuildGauss ()
{
    int i, j;

    for (i=2; i<=N; i++)
    {
        for (j=1; j<=N; j++)
            if (i!=j)
            {
                Gauss[i-1][i-1]+=CountE[i][j];

                if (j!=1)
                    Gauss[i-1][j-1]-=CountE[i][j];
            }

        if (i==N)
            Gauss[i-1][N]++;
    }
}

void DoGauss()
{
    int i, j, k, l, fnow;

    for (i=1, j=1; i<N && j<N; )
    {
        fnow=-1;

        for (k=i; k<N; k++)
            if (EPS<myabs(Gauss[k][j]))
            {
                fnow=k;
                break;
            }

        if (fnow==-1)
        {
            ++j;
            continue;
        }

        for (k=1; k<=N; k++)
            swap(Gauss[i][k], Gauss[fnow][k]);

        for (k=j+1; k<=N; k++)
            Gauss[i][k]/=Gauss[i][j];

        Gauss[i][j]=1;
        for (k=i+1; k<N; k++)
            if (Gauss[k][j]!=0)
            {
                for (l=j+1; l<=N; l++)
                    Gauss[k][l]-=Gauss[i][l]*Gauss[k][j];

                Gauss[k][j]=0;
            }

        i++;
        j++;
    }

    for (i=N-1; i>=1; i--)
        for (j=1; j<=N; j++)
            if (EPS<=myabs(Gauss[i][j]))
            {
                if (j==N)
                    foundsol=0;

                Sol[j]=Gauss[i][N];

                for (int k=i-1; k>=1; k--)
                {
                    Gauss[k][N]-=Sol[j]*Gauss[k][j];
                    Gauss[k][j]=0;
                }

                break;
            }

    if (!foundsol)
        Print(0);
}

void Solve ()
{
    int i, j;

    for (i=1; i<=N; i++)
        for (j=1; j<=N; j++)
            if (CountE[i][j]!=0)
                ANS=min(ANS, Cap[i][j]/myabs(Sol[j-1]-Sol[i-1]));
}

int main ()
{
    Read();

    DF(1);
    if (!Visited[N])
        Print(0);

    BuildGauss();
    DoGauss();
    Solve();
    Print(ANS);

    return 0;
}