Cod sursa(job #412570)

Utilizator RobytzzaIonescu Robert Marius Robytzza Data 5 martie 2010 20:11:45
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.41 kb
#include <stdio.h>
#include <queue>

using namespace std;

const int Lg = 355;
const int infinit =0x3f3f3f3f;

struct nod
{
    int inf,c;
    nod * next;
}*Graf[Lg];

int Cap[Lg][Lg];
int Cost[Lg][Lg];
int Dist[Lg];
int viz[Lg];
int tati[Lg];
int inc,sf,n,m;
int S,D;

struct cmp
{
    bool operator()(const int &a,const int &b)const
    {
        return Dist[a]>Dist[b];
    }
};

priority_queue <int, vector<int>,cmp> Q;

void add(nod *&a,int b,int v)
{
    nod *q=new nod;
    q->inf=b;
    q->c=v;
    q->next=a;
    a=q;
}

void citire()
{
    int a,b,c,cos;
    scanf ("%d %d %d %d",&n,&m,&S,&D);
    for (int i=0;i<m;i++)
    {
        scanf ("%d %d %d %d",&a,&b,&c,&cos);
        Cap[a][b]=c;
        Cost[a][b]=cos;
        Cost[b][a]=-cos;
        add(Graf[a],b,cos);
        add(Graf[b],a,-cos);
    }
}

int bell()
{
    for (int i=1;i<=n;i++)
    {
        Dist[i]=infinit;
        tati[i]=0;
        viz[i]=0;
    }
    tati[S]=-1;
    Dist[S]=0;
    inc=sf=0;
    Q.push(S);
    viz[S]=1;
    int top;
    while (!Q.empty())
    {
        top=Q.top();
        Q.pop();
        viz[top]=0;
        for (nod *i=Graf[top];i;i=i->next)
            if (Cap[top][i->inf])
            {
                if (Dist[i->inf] > Dist[top] + i->c)
                {
                    Dist[i->inf]=Dist[top]+i->c;
                    tati[i->inf]=top;
                    if (!viz[i->inf])
                    {
                        viz[i->inf]=1;
                        Q.push(i->inf);
                    }
                }
            }
    }
    if (Dist[D]!=infinit)
        return 1;
    return 0;
}

int min(int a,int b)
{
    return a<b?a:b;
}


void solve()
{
    int Rez=0;
    while (bell())
    {
            int fl=infinit;
            int nod=D;
            while (nod!=S)
            {
                fl=min(fl,Cap[tati[nod]][nod]);
                nod=tati[nod];
            }
            if (!fl)
                continue;
            nod=D;
            while (nod!=S)
            {
                Cap[tati[nod]][nod]-=fl;
                Cap[nod][tati[nod]]+=fl;
                nod=tati[nod];
            }
            Rez+=fl*Dist[D];
        }
    printf("%d\n",Rez);
}


int main ()
{
    freopen ("fmcm.in","r",stdin);
    freopen ("fmcm.out","w",stdout);
    citire();
    solve();
    return 0;
}