Cod sursa(job #2962377)

Utilizator horiacoolNedelcu Horia Alexandru horiacool Data 8 ianuarie 2023 14:43:21
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.24 kb
// Complexitate: Problema Cuplajului maximal in graf bipartit
// se rezolva cu  algoritmu lui lui Hopcroft Karp care are complexitatea
// O(sqrt(V)*E), unde V - numarul de noduri, E - numarul de muchii

#include <vector>
#include <queue>
#include <cstring>
#include <fstream>

using namespace std;

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

#define V_MAX  10001
#define E_MAX 100001

#define NOT_MATCHED_YET 0


int N, M, E;
bool visited[V_MAX];
vector<int> neighbors[V_MAX];
int left_partition[V_MAX], right_partition[V_MAX];

// functia care realizeaza cuplajul celor doua partitii
bool try_matching(int node)
{
    if (visited[node])
        return false;

    visited[node] = true;

    // cautam prin vecinii nodului daca mai exista unul necuplat inca
    for (auto neigh : neighbors[node]) {
        if (right_partition[neigh] == NOT_MATCHED_YET) {
            left_partition[node]   = neigh;
            right_partition[neigh] = node;
            return true;
        }
    }
    
    // ne uitam daca putem cupla persoanele
    // din cealalta partitie cu alte persoane
    for (auto neigh : neighbors[node]) {
        if (try_matching(right_partition[neigh])) {
            left_partition[node]   = neigh;
            right_partition[neigh] = node;
            return true;
        }
    }

    return false;
}

int main() {
    int x, y, matching = 0;
    bool matched;

    fin >> N >> M >> E;

    for (int i = 1; i <= E; ++i) {
        fin >> x >> y;

        // avem flux de la stanga la dreapta 
        neighbors[x].push_back(y);
    }

    // cat timp reusim sa efectuam cuplaje
    do {
        matched = false;
        memset(visited, false, sizeof(visited));

        for (int i = 1; i <= N; ++i) {
            // cautam nodurile care nu au pereche
            if (left_partition[i] == NOT_MATCHED_YET) {
                matched |= try_matching(i);
            }
        }
    } while (matched);

    // numarul de cuplaje
    for (int i = 1; i <= N; ++i) {
        if (left_partition[i] != NOT_MATCHED_YET) {
            ++matching;
        }
    }

    fout << matching << '\n';

    for(int i = 1; i <= N; ++i) {
        if (left_partition[i] != NOT_MATCHED_YET) {
            fout << i << ' ' << left_partition[i] << '\n';
        }
    }

    return 0;
}