Cod sursa(job #2950746)

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

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() {
    // memset(tata, 0, sizeof(tata));
    // 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(nod == d) {
        //     return true;
        // }

        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;
                    }
                }
            }
        }
    } 
    // return dPlus[d] != inf;
    // return false;

    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());

    cout << minCost << '\n';

    return 0;
}