Cod sursa(job #793356)

Utilizator tzipleatudTudor Tiplea tzipleatud Data 2 octombrie 2012 18:10:26
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 3.25 kb
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>
#define INF 0x3f3f3f3f
#define NM 360
#define nod first
#define cost second
#define VM 10100

using namespace std;

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

typedef pair<int, int> PI;

struct QCMP
{
    bool operator () (const PI& a, const PI& b) const
    {
        return a.cost>b.cost;
    }
};

queue <int> QB;

vector<int> G[NM];
vector<int>::iterator it;

int N,M,i,j,S,D,ND;
int Sum;
int C[NM][NM],F[NM][NM];
int Cost[NM][NM];
int Dist[NM];
int T[NM];
int a,b,c,d;
int ANS,FMIN;
int K;
int H[NM],Poz[NM];

bool BF ()
{
    memset(Dist,INF,sizeof(Dist));
    Dist[S]=0;
    QB.push(S);

    while (!QB.empty())
    {
        a=QB.front();
        QB.pop();
        for (it=G[a].begin(); it!=G[a].end(); ++it)
        {
            if (C[a][*it]-F[a][*it]<=0 || Dist[a]+Cost[a][*it]>=Dist[*it]) continue;

            Dist[*it]=Dist[a]+Cost[a][*it];
            T[*it]=a;
            QB.push(*it);
        }
    }

    return Dist[D]<INF;
}

void Up (int P)
{
    while (P>1 && Dist[H[P]]<Dist[H[P/2]])
    {
        swap(H[P],H[P/2]);
        swap(Poz[H[P]],Poz[H[P/2]]);
        P/=2;
    }
}

void Insert (int X)
{
    H[++K]=X;
    Poz[X]=K;
    Up(K);
}

void Down (int P)
{
    int Y=0;
    while (P!=Y)
    {
        Y=P;
        if (2*P<=K && Dist[H[2*P]]>Dist[H[K]])
        {
            swap(H[P],H[2*P]);
            swap(Poz[H[P]],Poz[H[2*P]]);
            Y=P*2;
        }
        if (2*P+1<=K && Dist[H[2*P+1]]>Dist[H[K]])
        {
            swap(H[P],H[2*P+1]);
            swap(Poz[H[P]],Poz[H[2*P+1]]);
            Y=2*P+1;
        }
        if (Y!=P) P=Y,Y=0;
    }
}

int GetTop ()
{
    int X=H[1];
    swap(H[1],H[K]);
    swap(Poz[H[1]],Poz[H[K]]);

    Poz[H[K]]=0;
    H[K]=0;
    --K;
    Down(1);

    return X;
}

bool Dijkstra ()
{

    for (i=1; i<=N; i++)
        for (it=G[i].begin(); it!=G[i].end(); ++it)
            if (Dist[i]<INF && Dist[*it]<INF)
                Cost[i][*it]+=Dist[i]-Dist[*it];

    for (i=0; i<=N; i++)
        Dist[i]=INF;
    Dist[S]=0;
    K=0;
    Insert(S);

    while (K)
    {
        a=GetTop();

        for (it=G[a].begin(); it!=G[a].end(); ++it)
        {
            if (C[a][*it]-F[a][*it]<=0 || Dist[a]+Cost[a][*it]>=Dist[*it]) continue;

            Dist[*it]=Dist[a]+Cost[a][*it];
            T[*it]=a;
            if (Poz[*it])
                Up(Poz[*it]);
            else
                Insert(*it);
        }
    }

    return Dist[D]<INF;
}

int main ()
{
    f >> N >> M >> S >> D;

    for (i=1; i<=M; i++)
    {
        f >> a >> b >> c >> d;
        G[a].push_back(b);
        G[b].push_back(a);
        C[a][b]+=c;
        Cost[a][b]=d;
        Cost[b][a]=-d;
    }

    BF();
    Sum=Dist[D];

    while (Dijkstra())
    {
        FMIN=INF;

        for (i=D; i!=S; i=T[i])
            FMIN=min(FMIN,C[T[i]][i]-F[T[i]][i]);

        for (i=D; i!=S; i=T[i])
        {
            F[T[i]][i]+=FMIN;
            F[i][T[i]]-=FMIN;
        }

        Sum+=Dist[D];
        ANS+=Sum*FMIN;
    }

    g << ANS << '\n';

    f.close();
    g.close();
    return 0;
}