Cod sursa(job #2962170)

Utilizator alex2209alexPavel Alexandru alex2209alex Data 7 ianuarie 2023 21:45:41
Problema Cuplaj maxim in graf bipartit Scor 16
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.8 kb
// Complexitate O(N * M)
#include <fstream>
#include <vector>
#include <queue>

using namespace std;
ifstream f("cuplaj.in");
ofstream g("cuplaj.out");
int n, m, destinatie, capacitate[1001][1001], parinte[1001];
vector<vector<int> > muchii;

void citeste();
int edmondsKarp();

int main()
{
    citeste();
    g << edmondsKarp();
    g.close();
    return 0;
}

bool bfs() {
    vector<bool> ap;
    queue<int> q;
    ap.resize(destinatie + 1);
    // Adaug sursa in coada
    q.push(0);
    ap[0] = true;
    // Cat timp mai am elemente in coada
    while(!q.empty()){
        int nod = q.front();
        q.pop();
        // Verific daca pot sa mai pun flow pe muchiile catre vecinii nodului curent
        for(auto it : muchii[nod]){
            // Daca vecinul nu e vizitat si se poate adauga flow pe muchia de la nod la el
            if(!ap[it] && capacitate[nod][it]){
                // Parintele vecinului este nodul curent si vecinul e vizitat si adaugat in coada
                parinte[it] = nod;
                ap[it] = true;
                q.push(it);
                // Daca vecinul este destinatia atunci am gasit un drum bun
                if(it == destinatie)
                    return true;
            }
        }
    }
    // Daca ajung aici nu mai sunt drumuri bune
    return false;
}

int edmondsKarp()
{
    int raspuns = 0;
    // Cat timp mai gasesc un drum pana la destinatie pe care pot adauga flow
    while(bfs()) {
        // Determin flow-ul maxim pe care il pot adauga drumului
        int nod = destinatie, newFlow = 1000000000;
        while(nod != 0) {
            int par = parinte[nod];
            if(capacitate[par][nod] < newFlow) {
                newFlow = capacitate[par][nod];
            }
            nod = par;
        }
        // Adaug la toate muchiile de pe drum flow-ul maxim
        nod = destinatie;
        while(nod != 0) {
            int par = parinte[nod];
            capacitate[par][nod] -= newFlow;
            capacitate[nod][par] += newFlow;
            nod = par;
        }
        // Adaug flow-ul gasit la raspuns
        raspuns += newFlow;
    }
    return raspuns;
}

void citeste()
{
    int e;
    f >> n >> m >> e;
    destinatie = n + m + 1;
    muchii.assign(destinatie + 1, vector<int>());
    while(e--) {
        int x, y;
        f >> x >> y;
        muchii[x].push_back(y + n);
        muchii[y + n].push_back(x);
        capacitate[x][y + n] = 1;
    }
    for(int i = 1; i <= n; ++i) {
        muchii[0].push_back(i);
        muchii[i].push_back(0);
        capacitate[0][i] = 1;
    }
    for(int i = 1; i <= m; ++i) {
        muchii[i + n].push_back(destinatie);
        muchii[destinatie].push_back(i + n);
        capacitate[i + n][destinatie] = 1;
    }
    f.close();
}