Cod sursa(job #2961799)

Utilizator PepiNedelcu Radu Pepi Data 7 ianuarie 2023 01:17:23
Problema Flux maxim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.35 kb
#include <bits/stdc++.h>


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

int flow = 0, n, m;

/*
    Idee: a) Pentru flux maxim am folosit ideea cu graf rezidual, in care pentru fiecare
        muchie avem si muchia inversa dar cu cost 0, gasim un drum cu muchii nesaturate(cost nenul)
        de la sursa la destinatie, si apoi scadem fluxul minim din muchiile pe care am venit si il adunam
        pe inversele lor. Repetam asta pana cand nu mai gasim niciun drum. Avem si optimizarea  in
        care dupa ce gasim un drum, ne intoarcem sa modificam toate drumurile care mai exista.
        Graful rezidual l am integrat in graful original, dupa explicatiile lui tushar:
        https://www.youtube.com/watch?v=GiN3jRdgxU4&t=366s&ab_channel=TusharRoy-CodingMadeSimple
*/


int matrice[1001][1001], tata[1001], visited[1001];
queue <int> q;

int bfs(){

    for(int i=1;i<=n;i++){
        visited[i] = 0;
        tata[i] = 0;
    }


    queue<int> empty;
    swap( q, empty ); // golim stiva

    //incepem bfs de la nodul 1

    q.push(1);
    visited[1] = 1;

    while(!q.empty()){

        if(q.front() == n){
            return 1;
        }

        int elem = q.front();
        q.pop();

        for(int i=1; i<=n;i++){
            if(visited[i] == 0 && matrice[elem][i]>0 ){
                tata[i]=elem;
                visited[i] = 1;
                q.push(i);

            }
        }



    }
    return 0;


}


int main() {

    fin>>n>>m;
    int a,b;
    for(int i=1;i<=m;i++){
        fin>>a>>b;
        fin>>matrice[a][b];
    }

    int rez = 0;

    while(bfs()){


        for(int i=1;i<=n;i++){
            int aux = 2000000000;
            if(visited[i] && matrice[i][n] > 0) {

                int nod = n;
                //reconstruim drumul, folosind vectorul de tati si calculam valoarea cu care se poate traversa
                while (tata[nod] > 0) {
                    aux = min(aux, matrice[tata[nod]][nod]);
                    nod = tata[nod];

                }


                //actualizam valorile

                 nod = n;

                while (tata[nod] > 0) {
                    matrice[tata[nod]][nod] -= aux;
                    matrice[nod][tata[nod]] += aux;

                    nod = tata[nod];

                }
                rez += aux;

            }


        }



    }

    fout<<rez;


    return 0;
}