Cod sursa(job #624526)

Utilizator rootsroots1 roots Data 22 octombrie 2011 14:26:15
Problema Flux Scor 52
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.26 kb
#include <fstream>
#include <cstring>
#include <iomanip>

#define fSize 101
#define useSize 101
#define grafSize 101
#define edgeSize 5001
#define levelSize 101

#define eWidth 102
#define eHeight 101

using namespace std;

ifstream in;
ofstream out;

struct vedge
{
    int x,y,c;
}edge[edgeSize];

struct gnod
{
    int nod;
    gnod *link;
}*graf[grafSize];

int level[levelSize];

double e[eHeight][eWidth];
double f[fSize];

bool use[useSize];

inline void addedge(int x,int y)
{
    gnod *p;

    p=new gnod;
    p->nod=y;
    p->link=graf[x];
    graf[x]=p;
}

inline void DFS(int nod)
{
    use[nod]=true;

    for(gnod *p=graf[nod];p;p=p->link)
        if(level[p->nod]==0)
        {
            level[p->nod]=level[nod]+1;

            ++e[nod][nod];
            --e[nod][p->nod];
            --e[p->nod][nod];
            ++e[p->nod][p->nod];

            DFS(p->nod);
        }
        else
        if(level[p->nod]>level[nod])
        {
            ++e[nod][nod];
            --e[nod][p->nod];
            --e[p->nod][nod];
            ++e[p->nod][p->nod];
        }
}

inline double min(double x,double y)
{
    if(x<y) return x;
    else return y;
}

inline double abs(double x)
{
    if(x<0) return -x;
    else return x;
}

int main()
{
    int M,N,pos;
    double aux;

    in.open("flux.in");

    in>>N>>M;
    for(int i=1;i<=M;++i)
    {
        in>>edge[i].x>>edge[i].y>>edge[i].c;
        addedge(edge[i].x,edge[i].y);
        addedge(edge[i].y,edge[i].x);
    }

    in.close();

    memset(e,0,sizeof(e));
    memset(f,0,sizeof(f));
    memset(level,0,sizeof(level));
    memset(use,false,sizeof(use));

    level[1]=1;
    DFS(1);

    if(!use[N])
    {
        out.open("flux.out");
        out<<"0.000\n";
        out.close();

        return 0;
    }

    //Gauss

    e[N][N+1]=-1;
    for(int row=2,col=2;row<=N;++row)
    {
        if(!use[col]) continue;

        if(e[row][col]==0)
        {
            pos=0;
            for(int j=col+1;j<=N;++j)
                if(e[j][row]!=0&&use[j])
                {
                    pos=j;
                    break;
                }

            for(int j=col;j<=N+1;++j)
            {
                aux=e[row][j];
                e[row][j]=e[pos][j];
                e[pos][j]=aux;
            }
        }

        for(int j=col+1;j<=N+1;++j)
            e[row][j]/=e[row][col];
        e[row][col]=1;

        for(int j=row+1;j<=N;++j)
            if(use[j])
            {
                for(int k=col+1;k<=N+1;++k)
                    e[j][k]-=e[row][k]*e[j][col];
                e[j][col]=0;
            }

        ++col;
    }

    for(int row=N,col=N;row>1;--row)
        if(use[row])
        {
            f[col]=e[row][N+1];
            for(int j=col+1;j<=N;++j)
                if(use[j]) f[col]-=e[row][j]*f[j];
            --col;
        }

    double flux=10001;

    for(int i=1;i<=M;++i)
        //if(use[edge[i].x]&&use[edge[i].y])
        {
            double cost=edge[i].c;
            flux=min(flux,cost/abs(f[edge[i].x]-f[edge[i].y]));
        }

    out.open("flux.out");

    out<<fixed<<setprecision(3)<<flux<<'\n';

    out.close();

    return 0;
}