Cod sursa(job #2962179)

Utilizator alex2209alexPavel Alexandru alex2209alex Data 7 ianuarie 2023 21:56:26
Problema Cuplaj maxim in graf bipartit Scor 16
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.54 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, pereche[20002];
pair<int,int> parinte[20002];
vector<vector<pair<int, int>> > muchii;

void citeste();
int edmondsKarp();

int main()
{
    citeste();
    g << edmondsKarp() << '\n';
    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
        int nrMuchie = 0;
        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.first]){
                // Parintele vecinului este nodul curent si vecinul e vizitat si adaugat in coada
                parinte[it.first] = {nod, nrMuchie};
                ap[it.first] = true;
                q.push(it.first);
                // Daca vecinul este destinatia atunci am gasit un drum bun
                if(it.first == destinatie)
                    return true;
                nrMuchie++;
            }
        }
    }
    // 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()) {
        int nod = destinatie;
        nod = destinatie;
        while(nod != 0) {
            int par = parinte[nod].first;
            int nrMuchie = parinte[nod].second;
            int t = muchii[par][nrMuchie].second;
            // Sterg muchia
            swap(muchii[par][nrMuchie], muchii[par][muchii[par].size() - 1]);
            muchii[par].pop_back();
            // Adaug muchia inversa
            muchii[nod].push_back({par, 1 - t});
            nod = par;
        }
        raspuns++;
    }
    return raspuns;
}

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