Cod sursa(job #2962225)

Utilizator alex2209alexPavel Alexandru alex2209alex Data 8 ianuarie 2023 00:10:36
Problema Cuplaj maxim in graf bipartit Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.29 kb
// Complexitate O(N * M)
#include <fstream>
#include <vector>
#include <queue>

using namespace std;
ifstream f("cuplaj.in");
ofstream g("cuplaj.out");
struct str {
    int nod, destinatie, capacitate;
};
int n, m, destinatie, raspuns, nrMuchii = -1;
vector<int> muchiiId[20002], parinte, ap;
vector<str> muchii;
queue<int> q;

void citeste(), adaugaSursaSiDestinatie();
int flux();

int main()
{
    citeste();
    adaugaSursaSiDestinatie();
    g << flux() << '\n';
    g.close();
    return 0;
}

bool bfs() {
    parinte.clear();
    parinte.resize(destinatie + 2);
    ap.clear();
    ap.resize(destinatie + 2);
    // Adaug sursa in coada
    q.push(0);
    ap[0] = 1;
    // Cat timp mai am elemente in coada
    while(!q.empty()){
        int nod = q.front();
        q.pop();
        if(nod == destinatie)
            continue;
        // Verific daca pot sa mai pun flow pe muchiile catre vecinii nodului curent
        for(auto it : muchiiId[nod]){
            // Daca vecinul nu e vizitat si se poate adauga flow pe muchia de la nod la el
            if(!ap[muchii[it].destinatie] && muchii[it].capacitate){
                // Parintele vecinului este nodul curent si vecinul e vizitat si adaugat in coada
                parinte[muchii[it].destinatie] = it;
                ap[muchii[it].destinatie] = 1;
                q.push(muchii[it].destinatie);
            }
        }
    }
    return ap[destinatie];
}

int flux()
{
    while(bfs()) {
        for(auto it : muchiiId[destinatie]){
            if(ap[muchii[it].destinatie] && muchii[it - 1].capacitate) {
                int nod = destinatie, flux = 1;
                while(nod != 0) {
                    flux = min(flux, muchii[parinte[nod]].capacitate);
                    nod = muchii[parinte[nod]].nod;
                }
                nod = destinatie;
                while(nod != 0 && flux != 0) {
                    int muchieInversa = parinte[nod] + 1;
                    if(parinte[nod] % 2) {
                        muchieInversa = parinte[nod] - 1;
                    }
                    muchii[parinte[nod]].capacitate -= flux;
                    muchii[muchieInversa].capacitate += flux;
                    nod = muchii[parinte[nod]].nod;
                }
                raspuns += flux;
            }
        }
    }
    return raspuns;
}

void adaugaSursaSiDestinatie() {
    for(int i = 1; i <= n; ++i) {
        nrMuchii++;
        muchii.push_back({0, i, 1});
        muchiiId[0].push_back(nrMuchii);
        nrMuchii++;
        muchii.push_back({i, 0, 0});
        muchiiId[i].push_back(nrMuchii);
    }
    for(int i = 1; i <= m; ++i) {
        nrMuchii++;
        muchii.push_back({i + n, destinatie, 1});
        muchiiId[i + n].push_back(nrMuchii);
        nrMuchii++;
        muchii.push_back({destinatie, i + n, 0});
        muchiiId[destinatie].push_back(nrMuchii);
    }
}

void citeste()
{
    int e;
    f >> n >> m >> e;
    destinatie = n + m + 1;
    while(e--) {
        int x, y;
        f >> x >> y;
        nrMuchii++;
        muchii.push_back({x, y + n, 1});
        muchiiId[x].push_back(nrMuchii);
        nrMuchii++;
        muchii.push_back({y + n, x, 0});
        muchiiId[y + n].push_back(nrMuchii);
    }
    f.close();
}