Cod sursa(job #2134679)

Utilizator danyvsDan Castan danyvs Data 18 februarie 2018 11:18:23
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.79 kb
#include <fstream>
#include <vector>

using namespace std;

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

const int NMAX = 10005;

int n, m, e;
vector<int> G[NMAX];
int st[NMAX]; // st[i] = nodul cu care se cupleaza nodul i din B
int dr[NMAX]; // dr[i] = nodul cu care se cupleaza nodul i din A
int cuplajMax; // numarul de muchii din cuplajul maxim
bool seen[NMAX]; // seeen[i] = true, daca nodul i din A este cuplat

void read() {
    fin >> n >> m >> e;
    for (int i = 0; i < e; ++ i) {
        int x, y;
        fin >> x >> y;
        G[x].push_back(y);
    }
}

bool match(int k) {
    // incerc sa cuplez nodul k
    // returneaza true, daca reusesc
    if (seen[k]) {
        // k este deja cuplat
        return false;
    }
    seen[k] = true;
    for (auto itr : G[k])
        if (dr[itr] == 0) {
            // i este necuplat
            st[k] = itr;
            dr[itr] = k;
            return true;
        }
    // nu am putut cupla k
    // se parcurge inca o data G[k] si se incearca cuplarea pe k cu un nod cuplat
    for (auto itr : G[k])
        if (match(dr[itr])) {
            st[k] = itr;
            dr[itr] = k;
            return true;
        }
    return false;
}

void solve() {
    bool done = false;
    while (!done) {
        done = true;
        for (int i = 1; i <= n; ++ i)
            seen[i] = false;
        for (int i = 1; i <= n; ++ i)
            if (!st[i] && match(i)) {
                ++ cuplajMax;
                done = false;
            }
    }
    fout << cuplajMax << "\n";
    for (int i = 1; i <= n; ++ i)
        if (st[i])
            fout << i << " " << st[i] << "\n";
    fout << "\n";
}

int main() {
    read();
    fin.close();
    solve();
    fout.close();
    return 0;
}