Cod sursa(job #3231996)

Utilizator sasha30ro@gmail.comManea Alexia Ioana [email protected] Data 28 mai 2024 17:07:36
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.05 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
typedef pair<int,int> pii;
const int INF = 1e9;

// Variabile globale
int n, m, cap[355][355], cost[355][355], old_d[355], d[355], real_d[355], S, D, ans, from[355], use[355];
vector<int> muchii[355];

// Funcția Bellman-Ford pentru a inițializa distanțele minime de la sursă la toate nodurile
void bellman() {
    for(int i = 1; i <= n; i++)
        old_d[i] = INF;  // Inițializăm toate distanțele cu infinit
    old_d[S] = 0;  // Distanța de la sursă la ea însăși este 0
    queue<int> coada;
    coada.push(S);
    while(!coada.empty()) {
        int nod = coada.front();
        coada.pop();
        for(int i : muchii[nod])
            if(cap[nod][i] > 0 && old_d[i] > old_d[nod] + cost[nod][i]) {
                old_d[i] = old_d[nod] + cost[nod][i];  // Actualizăm distanța minimă
                coada.push(i);
            }
    }
}

// Funcția pentru a găsi fluxul cu cost minim folosind algoritmul Dijkstra modificat
bool flux() {
    for(int i = 1; i <= n; i++) {
        real_d[i] = INF;
        d[i] = INF;
        from[i] = 0;
        use[i] = 0;
    }
    d[S] = 0;
    real_d[S] = 0;
    priority_queue<pii, vector<pii>, greater<pii>> pq;
    pq.push({0, S});
    while(!pq.empty()) {
        int nod = pq.top().second;
        pq.pop();
        if(use[nod])
            continue;
        use[nod] = 1;
        for(int i : muchii[nod])
            if(cap[nod][i] > 0 && d[i] > d[nod] + cost[nod][i] + old_d[nod] - old_d[i]) {
                d[i] = d[nod] + cost[nod][i] + old_d[nod] - old_d[i];  // Actualizăm distanța
                real_d[i] = real_d[nod] + cost[nod][i];  // Actualizăm costul real
                from[i] = nod;  // Salvăm drumul parcurs
                pq.push({d[i], i});
            }
    }
    for(int i = 1; i <= n; i++)
        old_d[i] = real_d[i];  // Actualizăm distanțele pentru următoarea iterație
    if(d[D] == INF)
        return 0;
    int minim = INF;
    for(int i = D; i != S; i = from[i])
        minim = min(minim, cap[from[i]][i]);  // Găsim capacitatea minimă pe drumul determinat
    ans += minim * real_d[D];  // Adăugăm costul minim la rezultatul final
    for(int i = D; i != S; i = from[i]) {
        cap[from[i]][i] -= minim;  // Actualizăm capacitățile pe drumul parcurs
        cap[i][from[i]] += minim;  // Actualizăm capacitățile inverse
    }
    return 1;
}

int main() {
    ios_base::sync_with_stdio(false);
    fin.tie(0);
    fin >> n >> m >> S >> D;
    for(int i = 1; i <= m; i++) {
        int a, b, c, d;
        fin >> a >> b >> c >> d;
        muchii[a].push_back(b);
        muchii[b].push_back(a);
        cap[a][b] = c;
        cost[a][b] = d;
        cost[b][a] = -d;
    }
    bellman();  // Inițializăm distanțele minime cu Bellman-Ford
    while(flux());  // Rulăm algoritmul de flux până nu mai putem îmbunătăți soluția
    fout << ans;  // Afișăm costul minim pentru fluxul maxim
    return 0;
}