Cod sursa(job #2967900)

Utilizator EdgarPaun Andrei Edgar Data 20 ianuarie 2023 12:22:07
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.68 kb
//Complexitate: O(n * m^2)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("maxflow.in");
ofstream fout("maxflow.out");
int destinatie, m; 
int capGrafRezidual[1001][1001], tata[1001];
vector<vector<int> > listaAdiacenta;



bool bfs() {
    vector<bool> vizitat;
    queue<int> q;
    vizitat.resize(destinatie + 1);
    // Stim ca nodul 1 e sursa si il punem in coada
    q.push(1);
    vizitat[1] = true;

    while(!q.empty()){
        int nod = q.front();
        q.pop();
        for(auto vecin : listaAdiacenta[nod]){
            // Daca vecinul nu e vizitat si se poate adauga flow pe muchia de la nod la el (capacitatea e mai mare decat 0)
            if(!vizitat[vecin] && capGrafRezidual[nod][vecin]){
                // Este updatat vectorul tata pentru a putea reconstrui drumul de ameliorare
                tata[vecin] = nod;
                vizitat[vecin] = true;
                q.push(vecin);
                // Daca vecinul este destinatia atunci am gasit un drum bun 
                // BFS-ul este optimizat pentru ca el se incide direct cand vecinul este destinatia
                if(vecin == destinatie)
                    return true;
            }
        }
    }
    return false;
}

int edmondsKarp()
{
    int raspuns = 0;
    // Cat timp mai gasesc un drum pana la destinatie pe care pot adauga flow
    while(bfs()) {
        int nod = destinatie, bottleNeck = 1000000000;
        while(nod != 1) {
            int parinte = tata[nod];
            if(capGrafRezidual[parinte][nod] < bottleNeck) {
                // Este calculata valoarea minima de pe drumul respectiv (bottleNeck), de la destinatie la sursa
                // folosind vectorul tata
                bottleNeck = capGrafRezidual[parinte][nod];
            }
            nod = parinte;
        }
        // Adaug la toate muchiile de pe drum flow-ul maxim
        nod = destinatie;
        while(nod != 1) {
            int parinte = tata[nod];
            capGrafRezidual[parinte][nod] -= bottleNeck; // Drum direct in graful rezidual
            capGrafRezidual[nod][parinte] += bottleNeck; // Drum invers in graful rezidual
            nod = parinte;
        }
        // Adaug flow-ul gasit la raspuns
        raspuns += bottleNeck;
    }

    return raspuns;
}


int main()
{
    fin >> destinatie >> m;
    listaAdiacenta.assign(destinatie + 1, vector<int>());

    while(m--) {
        int x, y, c;
        fin >> x >> y >> c;
        listaAdiacenta[x].push_back(y);
        listaAdiacenta[y].push_back(x);
        capGrafRezidual[x][y] = c;
    }

    fout << edmondsKarp();
    
    fin.close();
    fout.close();
    return 0;
}