Cod sursa(job #370091)

Utilizator DraStiKDragos Oprica DraStiK Data 30 noiembrie 2009 10:06:49
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.57 kb
#include <algorithm>
#include <vector>
using namespace std;

#define DIM 355
#define oo 1<<31-1
#define pb push_back

int q[DIM*DIM],t[DIM],dst[DIM],h[DIM],poz[DIM];
int c[DIM][DIM],f[DIM][DIM],ct[DIM][DIM];
vector <int> lst[DIM];
int n,m,s,d,minim,l;
long long cost,sum;

void read ()
{
    int i,x,y,z,t;

    scanf ("%d%d%d%d",&n,&m,&s,&d);
    for (i=1; i<=m; ++i)
    {
        scanf ("%d%d%d%d",&x,&y,&z,&t);
        lst[x].pb (y);
        lst[y].pb (x);
        c[x][y]=z;
        ct[x][y]=t;
        ct[y][x]=-t;
    }
}

void bellman_ford ()
{
    int st,dr,i;

    for (i=1; i<=n; ++i)
        dst[i]=oo;
    for (dst[q[st=dr=1]=s]=0; st<=dr; t[q[st++]]=0)
        for (i=0; i<(int)lst[q[st]].size (); ++i)
            if (c[q[st]][lst[q[st]][i]]>f[q[st]][lst[q[st]][i]] && dst[q[st]]+ct[q[st]][lst[q[st]][i]]<dst[lst[q[st]][i]])
            {
                dst[lst[q[st]][i]]=dst[q[st]]+ct[q[st]][lst[q[st]][i]];
                if (!t[lst[q[st]][i]])
                    t[q[++dr]=lst[q[st]][i]]=1;
            }
    sum=(long long)dst[d];
}

inline void downheap (int nod)
{
    int fiu;

    for ( ; nod<=l; )
    {
        if ((nod<<1)<=l)
        {
            fiu=nod<<1;
            if (fiu+1<=l)
                if (dst[h[fiu+1]]<dst[h[fiu]])
                    ++fiu;
        }
        else
            return ;
        if (dst[h[nod]]>dst[h[fiu]])
        {
            poz[h[nod]]=fiu;
            poz[h[fiu]]=nod;
            swap(h[nod],h[fiu]);
            nod=fiu;
        }
        else
            return ;
    }
}

inline void upheap(int nod)
{
    int tata;

    for ( ; nod>1; )
    {
        tata=nod>>1;
        if (dst[h[tata]]>dst[h[nod]])
        {
            poz[h[nod]]=tata;
            poz[h[tata]]=nod;
            swap(h[tata],h[nod]);
            nod=tata;
        }
        else
            return ;
    }
}

int dijkstra ()
{
    int i,j,nrmin;

    for (i=1; i<=n; ++i)
        for (j=0; j<(int)lst[i].size (); ++j)
            if (dst[i]!=oo && dst[lst[i][j]]!=oo)
                ct[i][lst[i][j]]+=dst[i]-dst[lst[i][j]];
    for (i=1; i<=n; ++i)
    {
        t[i]=0;
        dst[i]=oo;
        poz[i]=-1;
    }
    for (dst[h[l=1]=s]=0, poz[s]=1; l; )
    {
        nrmin=h[1];
        h[1]=h[l--];
        poz[h[1]]=1;
        downheap (1);
        for (i=0; i<(int)lst[nrmin].size (); ++i)
            if (c[nrmin][lst[nrmin][i]]>f[nrmin][lst[nrmin][i]] && dst[nrmin]+ct[nrmin][lst[nrmin][i]]<dst[lst[nrmin][i]])
            {
                dst[lst[nrmin][i]]=dst[nrmin]+ct[nrmin][lst[nrmin][i]];
                t[lst[nrmin][i]]=nrmin;
                if (poz[lst[nrmin][i]]!=-1)
                    upheap (poz[lst[nrmin][i]]);
                else
                {
                    poz[h[++l]=lst[nrmin][i]]=l;
                    upheap (l);
                }
            }
    }
    if (dst[d]!=oo)
        return 1;
    return 0;
}

inline int min (int a,int b)
{
    if (a<b)
        return a;
    return b;
}

void solve ()
{
    int i;

    for (minim=oo; dijkstra (); minim=oo)
    {
        for (i=d; i!=s; i=t[i])
            minim=min (minim,c[t[i]][i]-f[t[i]][i]);
        for (i=d; i!=s; i=t[i])
        {
            f[t[i]][i]+=minim;
            f[i][t[i]]-=minim;
        }
        sum+=dst[d];
        cost+=minim*sum;
    }
    printf ("%lld",cost);
}

int main ()
{
    freopen ("fmcm.in","r",stdin);
    freopen ("fmcm.out","w",stdout);

    read ();
    bellman_ford ();
    solve ();

    return 0;
}