Cod sursa(job #2358897)

Utilizator nurof3nCioc Alex-Andrei nurof3n Data 28 februarie 2019 14:04:42
Problema Cuplaj maxim in graf bipartit Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.7 kb
#include <fstream>
#include <cstdio>
#include <vector>

using namespace std;

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

const int N_MAX = 10000;

vector<int> Edges[N_MAX + 1];

int N, M, E;
int l[N_MAX + 1]; //reprezinta nodul pereche pt un nod din multimea stanga in cuplaj
int r[N_MAX + 1]; //reprezinta nodul pereche pt un nod din multimea dreapta in cuplaj
bool viz[N_MAX + 1]; //vectorul viz (pentru multimea stanga)

int Cuplaj(int x) { //returneaza 1 daca s-a cuplat nodul x (din multimea stanga)
    if(viz[x])
        return 0;

    viz[x] = true;
    for(auto y : Edges[x])
        if(!r[y]) {   //daca nici y nu are muchie incidenta in cuplaj, il cuplam pe x cu y
            l[x] = y;
            r[y] = x;
            return 1;
        }
    //daca nu am returnat 1, inseamna ca fiecare vecin y este deja cuplat, dar poate putem cupla un vecin y cu altul si sa il cuplam dupa pe x cu y
    for(auto y : Edges[x])
        if(Cuplaj(r[y])) {
            l[x] = y;
            r[y] = x;
            return 1;
        }
    return 0;
}

int main() {
    int x, y;
    in >> N >> M >> E;
    for(int i = 1; i <= E; ++i) {
        in >> x >> y;
        Edges[x].push_back(y);
    }

    bool change = true;
    while(change) {
        change = false;
        for(int i = 1; i <= N || i <= M; ++i)
            viz[i] = false;
        for(int i = 1; i <= N; ++i)
            if(!l[i])
                change = Cuplaj(i);
    }

    int cuplaj = 0;
    for(int i = 1; i <= N; ++i)
        if(l[i])
            ++cuplaj;

    out << cuplaj << '\n';
    for(int i = 1; i <= N; ++i)
        if(l[i])
            out << i << ' ' << l[i] << '\n';

    return 0;
}