Cod sursa(job #2958340)

Utilizator mirceaspPetcu Mircea mirceasp Data 26 decembrie 2022 01:23:48
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.49 kb
#include <iostream>
#include <bits/stdc++.h>
#include <fstream>
#define mx 351
#define minim min(x,flux)
using namespace std;
ifstream f("fmcm.in");
ofstream g("fmcm.out");
int n, m, x, y, capacitate, cost, s, d;
vector<vector<int>> lista;
vector<int> distante;
vector<int> distante_dijkstra;
pair<int, int> rgraf[mx][mx];
vector<int> distante_adevarata;


//----------------------------------------//
void bellmanFord() {
    for (int i = 0; i < n + 1; ++i) {
        distante.push_back(INT_MAX);
    }
    queue<int> q;
    q.push(s);
    distante[s] = 0;
    while (!q.empty()) {
        int front = q.front();
        q.pop();
        for (auto vecin: lista[front]) {
            if (rgraf[front][vecin].first > 0) {
                if (distante[front] + rgraf[front][vecin].second < distante[vecin]) {
                    distante[vecin] = distante[front] + rgraf[front][vecin].second;
                    q.push(vecin);
                }
            }
        }

    }
}

// tot un fel de parcurgere dfs doar ca verific daca se poate parcurge in cost minim
bool dijkstra(int tata[]) {
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
    distante_dijkstra.clear();distante_adevarata.clear();
    for (int i = 0; i < n + 1; ++i) {
        distante_dijkstra.push_back(INT_MAX);
        distante_adevarata.push_back(0);
    }
    distante_dijkstra[s] = 0;
    pq.push({0, s});
    while (!pq.empty())
    {
        auto per = pq.top();
        int nodCurent = per.second;
        int costNodCurent = per.first;
        pq.pop();
        if(costNodCurent <= distante_dijkstra[nodCurent]) {
            for (auto vecin: lista[nodCurent])
                if (rgraf[nodCurent][vecin].first > 0 && distante_dijkstra[nodCurent] + distante[nodCurent] + rgraf[nodCurent][vecin].second - distante[vecin] < distante_dijkstra[vecin]) {
                    distante_dijkstra[vecin] = distante_dijkstra[nodCurent] + distante[nodCurent] + rgraf[nodCurent][vecin].second - distante[vecin];
                    distante_adevarata[vecin] = distante_adevarata[nodCurent] + rgraf[nodCurent][vecin].second;
                    pq.push({distante_dijkstra[vecin], vecin});
                    tata[vecin] = nodCurent;
                }


        }
    }
    if (distante_dijkstra[d] != INT_MAX)
        return true;
    return false;
}

int main() {

    f >> n >> m >> s >> d;

    int tata[n + 1];
    for (int i = 1; i < n + 1; i++)
        tata[i] = -1;


    for (int i = 0; i < n + 1; ++i) {
        lista.push_back({});
    }

    for (int i = 0; i < m; ++i) {

        f >> x >> y >> capacitate >> cost;
        lista[x].push_back(y);
        lista[y].push_back(x);
        rgraf[x][y].first = capacitate;
        rgraf[x][y].second = cost;
        rgraf[y][x].second = -cost;
    }

    int fluxTotal = 0;
    bellmanFord();


    while (dijkstra(tata)) {

        int flux = INT_MAX;
        int u = d;
        while (u != s) {
            int x = rgraf[tata[u]][u].first;
            flux = minim;
            u = tata[u];
        }

        u = d;
        while (u != s) {
            int vecin = tata[u];
            rgraf[vecin][u].first -= flux;
            rgraf[u][vecin].first += flux;
            u = tata[u];
        }
        fluxTotal += flux * distante_adevarata[d];
        for (int i = 1; i < n + 1; i++)
            tata[i] = -1;

    }
    g << fluxTotal;

    f.close();
    g.close();
    return 0;
}