Cod sursa(job #2959465)

Utilizator Petrica81Simion Petrica Petrica81 Data 31 decembrie 2022 12:29:12
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.75 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

ifstream fin ("maxflow.in");
ofstream fout ("maxflow.out");

int n;
bool BFS(vector<vector<int>>& graf, vector<vector<int>>& capacitati, vector<int>& nivel){
    for(int i = 2; i <= n; i++)
        nivel[i] = -1;
    nivel[1] = 0;

    queue<int> q;
    q.push(1);

    while(!q.empty()){
        int nod = q.front();
        q.pop();
        for(int i = 0; i < graf[nod].size(); i++){
            int nod_aux = graf[nod][i];
            if (capacitati[nod][nod_aux] > 0 && nivel[nod_aux] < 0){
                nivel[nod_aux] = nivel[nod] + 1;
                q.push(nod_aux);
            }
        }
    }
    //daca nu ajung la destinatie returnez false
    if(nivel[n] < 0) return false;
    else return true;
};

int trimite_flux(vector<vector<int>>& graf, vector<vector<int>>& capacitati, vector<int>& nivel, vector<int>& count, int nod , int flow){
    if(nod == n)
        return flow;
    if(count[nod] == graf[nod].size())
        return 0;

    for(auto nod2 : graf[nod]){
        if(capacitati[nod][nod2] > 0){
            count[nod]++;
            if(nivel[nod2] == nivel[nod]+1){
                int flow_aux = min(flow,capacitati[nod][nod2]);

                int capac_minima = trimite_flux(graf,capacitati,nivel,count,nod2,flow_aux);
                if(capac_minima > 0){
                    if(capacitati[nod2][nod] == 0)
                        graf[nod2].push_back(nod);
                    capacitati[nod][nod2] -= capac_minima;
                    capacitati[nod2][nod] += capac_minima;

                    return capac_minima;
                }
            }
        }
    }


    return 0;
}

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

    vector<vector<int>> graf, capacitati; //lista de adiacenta, respectiv matrice cu capacitati
    graf.resize(n+1);
    capacitati.resize(n+1, vector<int> (n+1, 0));

    //citesc datele
    for(int i = 0; i < m; i++){
        int sursa,destinatie,cost;
        fin>>sursa>>destinatie>>cost;
        //daca am mai multe muchii intre aceleasi noduri, tin minte doar una si adun capacitatile
        if( capacitati[sursa][destinatie] == 0) {
            capacitati[sursa][destinatie] = cost;
            graf[sursa].push_back(destinatie);
        }
        else
            capacitati[sursa][destinatie] += cost;
    }
    //rezolvare (folosesc algoritmul lui dinic chiar daca nu este neaparat necesar)
    int flow_max = 0;
    vector<int> nivel(n+1,-1);

    while(BFS(graf, capacitati, nivel)){
        vector<int> count(n+1, 0);
        int aux = trimite_flux(graf,capacitati,nivel,count,1,10000);
        while(aux){
            flow_max += aux;
            aux = trimite_flux(graf,capacitati,nivel,count,1,10000);
        }
    }
    fout<<flow_max;
}