Cod sursa(job #2950759)

Utilizator RobertuRobert Udrea Robertu Data 4 decembrie 2022 17:10:32
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.06 kb
#include <bits/stdc++.h>
#define dim 360
#define inf 1e9 + 7
using namespace std;
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");

/*
    AM STAT TOATA DUPA AMIAZA CA NU MERGEA PT CA ACEL MEMSET DIN DIJKSTRA
    NU FACEA CE MA ASTEPTAM EU SA FACA

    In rest, ca idee, am calculat distantele reale folsind bellmanford ca mai apoi
    sa le pot folosi in dijkstra ca sa nu avem muchii cu coturi negative. Si cam atat
    Am mers dupa indicatii:))
*/

int n, m, s, d, x, y, c, z, minCost = 0, flow, altNod;
int a[dim][dim], cost[dim][dim], tata[dim], dBellman[dim], dPlus[dim], dReal[dim]; 
vector< vector<int> > lista(dim);
priority_queue< pair<int, int> , vector< pair<int, int> >, greater< pair<int, int> > > pCoada;

void BellmanFord() {
    vector<bool> inCoada(dim, false);
    queue<int> coada;
    memset(dBellman, inf, sizeof(dBellman));

    coada.push(s);
    inCoada[s] = true;
    dBellman[s] = 0;

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

        for(auto vecin : lista[nod]) {
            if(a[nod][vecin])
            if( dBellman[ vecin ] > dBellman[ nod ] + cost[nod][vecin]  ) {
                dBellman[ vecin ] = dBellman[ nod ] + cost[nod][vecin];
                if( !inCoada[ vecin ] ) {
                    coada.push( vecin );
                    inCoada[ vecin ] = true;
                }
            }
        }
    }
}

bool Dijkstra() {
    //FIRAR EL SA FIE CA MI-A MANCAT CATEVA ORE
    // memset(dPlus, inf, sizeof(dPlus));
    for(int i = 1; i <= n; i++) dPlus[i] = inf;
    dPlus[s] = 0;
    dReal[s] = 0;
    
    pCoada.push(make_pair(0, s));
    while( !pCoada.empty() ) {
        pair<int, int> front = pCoada.top();
        pCoada.pop();

        int nod = front.second;

        if(dPlus[nod] == front.first) {
            for(auto vecin : lista[nod]) {
                if(a[nod][vecin] > 0) {
                    if( dPlus[vecin] > dPlus[nod] + cost[nod][vecin] + dBellman[nod] - dBellman[vecin] ) {
                        dPlus[vecin] = dPlus[nod] + cost[nod][vecin] + dBellman[nod] - dBellman[vecin];
                        pCoada.push(make_pair(dPlus[vecin], vecin));
                        dReal[ vecin ] = dReal[ nod ] + cost[nod][vecin];
                        tata[vecin] = nod;
                    }
                }
            }
        }
    } 

    for(int i = 1; i <= n; i++) {
        dBellman[i] = dReal[i];
    }

    if(dPlus[d] == inf) return false;

    flow = inf;
    for(int nod = d; nod != s; nod = tata[nod]) {
        flow = min(flow, a[ tata[nod] ][nod]);
    }

    for(int nod = d; nod != s; nod = tata[nod]) {
        a[ tata[nod] ][nod] -= flow;
        a[nod][ tata[nod] ] += flow;
    }

    minCost += flow * dReal[d];
    return true;
}

int main() {
    fin >> n >> m >> s >> d;

    for(int i = 0; i < m; i++) {
        fin >> x >> y >> c >> z;
        lista[x].push_back(y);
        lista[y].push_back(x);
        a[x][y] = c;
        cost[x][y] = z;
        cost[y][x] = -z;
    }

    BellmanFord();
    while(Dijkstra());

    fout << minCost << '\n';

    return 0;
}