Cod sursa(job #1411972)

Utilizator Al3ks1002Alex Cociorva Al3ks1002 Data 1 aprilie 2015 01:38:00
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.2 kb
#include<cstdio>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<vector>
#include<bitset>
#include<deque>
#include<queue>
#include<set>
#include<map>
#include<cmath>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<unordered_map>

#define ll long long
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
#define pll pair<ll,ll>

using namespace std;
const int nmax = 355;
const int inf = (1LL << 31) - 1;

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];
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(auto it : V[From])
            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(auto it : V[From])
            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;
}