Cod sursa(job #1462596)

Utilizator CollermanAndrei Amariei Collerman Data 18 iulie 2015 16:24:51
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.92 kb
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
ofstream fout("fmcm.out");
ifstream fin("fmcm.in");
const int MMAX = 355;
const int NMAX = 1050;
const int INF = 1<<30;

int n, m, s, d, dist_aditionala;
long long flux_maxim;

bool inQueue[MMAX];
int Tata[MMAX], Drum[MMAX];
vector<int> Graf[NMAX];
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q; // min-heap

int Cost[MMAX][MMAX], GrafRezidual[MMAX][MMAX], C[MMAX][MMAX];

void citire()
{
    int x, y, z, w;

    fin >> n >> m >> s >> d;
    for(int i=1; i<=m; i++) {
        fin >> x >> y >> z >> w;
        Graf[x].push_back(y);
        Graf[y].push_back(x);
        C[x][y] = z;
        Cost[x][y] = w;
        Cost[y][x] = -w;
    }
}

void BellmanFord()
{
    queue<int> q;
    q.push(s);
    inQueue[s] = true;

    for(int i=1; i<=n; i++) Drum[i] = INF;
    Drum[s] = 0;

    while(!q.empty()) {
        int nod = q.front();
        q.pop();
        inQueue[nod] = false;

        for(auto x : Graf[nod])
        {
            if( (C[nod][x] > GrafRezidual[nod][x]) && ( Drum[x] > Drum[nod] + Cost[nod][x] ) ) {
                Drum[x] = Drum[nod] + Cost[nod][x];

                if(!inQueue[x]) {
                    q.push(x);
                    inQueue[x] = true;
                }
            }
        }
    }

    dist_aditionala += Drum[d];
}

void UpdateCosts()
{
    for(int i=1; i<=n; i++)
        if(Drum[i] != INF)
            for(auto x : Graf[i])
                if(Drum[x] != INF)
                    Cost[i][x] += (Drum[i] - Drum[x]);
}

bool Dijkstra()
{
    UpdateCosts();

    for(int i=1; i<=n; i++){
        Drum[i] = INF;
        Tata[i] = 0;
    }

    Drum[s] = 0;
    q.push(make_pair(s, 0));

    while(!q.empty()){
        int nod = q.top().first;
        int dist = q.top().second;
        q.pop();

        if(Drum[nod] != dist || nod == d) continue;

        for(auto x : Graf[nod]) {
            if( (Drum[x] > Drum[nod] + Cost[nod][x]) && (C[nod][x] > GrafRezidual[nod][x]) ) {
                Drum[x] = Drum[nod] + Cost[nod][x];
                Tata[x] = nod;
                q.push(make_pair(x, Drum[x]));
            }
        }
    }

    return (Drum[d] != INF);
}

int EdmondsKarp()
{
    while(Dijkstra())
    {
        int flux = INF;

        for(int v = d; v != s; v = Tata[v]) {
            int aux = Tata[v];
            flux = min(flux, C[aux][v] - GrafRezidual[aux][v]);
        }

        for(int v = d; v != s; v = Tata[v]) {
            int aux = Tata[v];
            GrafRezidual[aux][v] += flux;
            GrafRezidual[v][aux] -= flux;
        }

        dist_aditionala += Drum[d];
        flux_maxim += (flux * dist_aditionala);
    }

    return flux_maxim;
}

int main()
{
    citire();
    BellmanFord();
    fout << EdmondsKarp() << '\n';
    return 0;
}