Cod sursa(job #3227778)

Utilizator AnSeDraAndrei Sebastian Dragulescu AnSeDra Data 2 mai 2024 15:39:33
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.69 kb
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");

const int NrNoduriMax = 10005;
const int INF = 100005;
const int NIL = 0;

struct nod_stanga{
    vector<int> adj;
    int dist, pereche;
};

struct nod_drepata{
    int pereche;
};

int nr_left, nr_right, nr_muchii;
int cuplaj_maxim;
nod_stanga noduri_st[NrNoduriMax];
nod_drepata noduri_dr[NrNoduriMax];
queue<int> q;

void citire(){
    int nod1, nod2;

    fin >> nr_left >> nr_right >> nr_muchii;

    for(int i = 1; i <= nr_muchii; i++){
        fin >> nod1 >> nod2;
        noduri_st[nod1].adj.push_back(nod2);
    }
}

bool bfs(){
    for(int i = 1; i <= nr_left; i++){
        if(noduri_st[i].pereche == NIL){
            noduri_st[i].dist = 0;
            q.push(i);
        }
        else{
            noduri_st[i].dist = INF;
        }
    }
    noduri_st[NIL].dist = INF;

    while(!q.empty()){
        int nod = q.front();
        q.pop();

        if(noduri_st[nod].dist < noduri_st[NIL].dist){
            for(int vecin : noduri_st[nod].adj){
                int pereche = noduri_dr[vecin].pereche;

                if(noduri_st[pereche].dist == INF){
                    noduri_st[pereche].dist = noduri_st[nod].dist + 1;
                    q.push(pereche);
                }
            }
        }
    }

    return (noduri_st[NIL].dist != INF);
}

bool dfs(int nod){
    if(nod == NIL){
        return 1;
    }

    for(int vecin : noduri_st[nod].adj){
        int pereche = noduri_dr[vecin].pereche;

        if((noduri_st[pereche].dist == noduri_st[nod].dist + 1) && dfs(pereche)){
            noduri_st[nod].pereche = vecin;
            noduri_dr[vecin].pereche = nod;
            return 1;
        }
    }

    noduri_st[nod].dist = INF;
    return 0;
}

int hopcroft_karp(){
    for(int nod = 1; nod <= nr_left; nod++){
        noduri_st[nod].pereche = NIL;
    }

    for(int nod = 1; nod <= nr_right; nod++){
        noduri_dr[nod].pereche = NIL;
    }

    int cuplaj = 0;
    while(bfs()){
        for(int nod = 1; nod <= nr_left; nod++){
            if(noduri_st[nod].pereche == NIL && dfs(nod)){
                cuplaj++;
            }
        }
    }

    return cuplaj;
}

void reconstituire_perechi(){
    for(int nod = 1; nod <= nr_left; nod++){
        if(noduri_st[nod].pereche != NIL){
            fout << nod << " " << noduri_st[nod].pereche << '\n';
        }
    }
}

void afisare(){
    fout << cuplaj_maxim << '\n';
    reconstituire_perechi();
}

int main(){
    citire();

    cuplaj_maxim = hopcroft_karp();
    afisare();

    return 0;
}