Cod sursa(job #968134)

Utilizator Al3ks1002Alex Cociorva Al3ks1002 Data 1 iulie 2013 20:29:25
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.68 kb
#include<cstdio>
#include<vector>
#include<algorithm>
#include<deque>
#include<bitset>
#include<queue>

#define pb push_back
#define mp make_pair
#define PII pair<int,int>

using namespace std;
const int NMAX = 355;
const int INF = 1<<30;

int N,M,S,D,X,Y,C,Z,i,From,CostFrom,Where,CostWhere,MinFlow,MaxFlow,CostMuchie;
int Cap[NMAX][NMAX],Cost[NMAX][NMAX],Flow[NMAX][NMAX],Father[NMAX];
int DB[NMAX]; // Distanta Bellman
int DD[NMAX]; // Distanta Dijkstra
int DR[NMAX]; // Distanta reala Bellman dupa ce executam Dijkstra

vector<int> V[NMAX];
vector<int>::iterator it;
deque<int> Q;
bitset<NMAX> InQ;
priority_queue<PII,vector<PII>,greater<PII> > PQ;

void Read()
{
    freopen("fmcm.in","r",stdin);
    freopen("fmcm.out","w",stdout);
    scanf("%d%d%d%d",&N,&M,&S,&D);
    for(;M;M--)
    {
        scanf("%d%d%d%d",&X,&Y,&C,&Z);
        Cap[X][Y]=C; Cap[Y][X]=0;
        Cost[X][Y]=Z; Cost[Y][X]=-Z;
        V[X].pb(Y); V[Y].pb(X);
    }
}

void BellmanFord()
{
    for(i=1;i<=N;i++) DB[i]=INF;
    Q.pb(S); DB[S]=0;
    while(!Q.empty())
    {
        From=Q.front(); Q.pop_front(); InQ[From]=0;
        for(it=V[From].begin();it!=V[From].end();it++)
            if(Flow[From][*it]<Cap[From][*it] && DB[From]+Cost[From][*it]<DB[*it])
            {
                DB[*it]=DB[From]+Cost[From][*it];
                if(!InQ[*it]) {InQ[*it]=1; Q.pb(*it);}
            }
    }
}

int Dijkstra()
{
    for(i=1;i<=N;i++) DD[i]=INF;
    DD[S]=0; PQ.push(mp(0,S)); Father[S]=S;
    while(!PQ.empty())
    {
        From=PQ.top().second; CostFrom=PQ.top().first; PQ.pop();
        if(CostFrom>DD[From]) continue;
        for(it=V[From].begin();it!=V[From].end();it++)
            if(Flow[From][*it]<Cap[From][*it])
            {
                Where=*it; CostWhere=Cost[From][Where]+DB[From]-DB[Where];
                if(DD[From]+CostWhere<DD[Where])
                {
                    DD[Where]=DD[From]+CostWhere;
                    DR[Where]=DR[From]+Cost[From][Where];
                    Father[Where]=From;
                    PQ.push(mp(DD[Where],Where));
                }
            }
    }
    for(i=1;i<=N;i++) DB[i]=DR[i];
    return DD[D]!=INF;
}

void MaxFlowCostMin()
{
    while(Dijkstra())
    {
        for(MinFlow=INF,X=D;X!=Father[X];X=Father[X])
            MinFlow=min(MinFlow,Cap[Father[X]][X]-Flow[Father[X]][X]);
        for(X=D;X!=Father[X];X=Father[X])
        {
            Flow[Father[X]][X]+=MinFlow;
            Flow[X][Father[X]]-=MinFlow;
        }
        MaxFlow+=MinFlow*DB[D];
    }
    printf("%d\n",MaxFlow);
}

int main()
{
    Read();
    BellmanFord();
    MaxFlowCostMin();
    return 0;
}