Pagini recente » Cod sursa (job #2223458) | Cod sursa (job #1014461) | Cod sursa (job #2141832) | Cod sursa (job #502842) | Cod sursa (job #2179093)
// cuplaj - O(sqrt(n) * m)
#include <iostream>
#include <cstdio>
#include <fstream>
#include <vector>
#include <bitset>
#include <cassert>
#include <cstring>
#include <algorithm>
#define NMAX 10009
using namespace std;
ifstream f("cuplaj.in");
ofstream g("cuplaj.out");
int n, m, e, sol;
int dr[NMAX]; // dr[i] = pentru nodul i din stanga, cine este perechea lui din dreapta
int st[NMAX]; // st[i] = pentru nodul i din dreapta, cine este perechea lui din stanga
vector<int> G[NMAX];
bitset<NMAX> viz;
void read_input() {
f >> n >> m >> e;
for (int i = 1; i <= e; ++i) {
int x, y;
f >> x >> y;
G[x].push_back(y);
}
}
int cupleaza(int node) {
// daca nodul node din STANGA este vizitat
if (viz[node]) {
return 0; // nu il pot cupla
}
viz[node] = 1; // l-am vizitat
// incerc sa il cuplez pe node cu un nod din stanga NECUPLAT
for (auto it : G[node]) { // it e nod in dreapta
if (!st[it]) {
dr[node] = it;
st[it] = node;
return 1; // am reusit sa cuplez fara sa schimb ceva cuplat deja
}
}
// vedem daca putem sa recuplam alte noduri fara sa micsoram solutia si sa il cuplam si pe node
for (auto it : G[node]) { // it este nod in dreapta
// st[it] != 0: it din dreapta este cuplat cu st[it] din stanga
// cupleaza(st[it]) incearca sa il recupleze pe st[it], fara sa miscoreze solutia
if (st[it] != 0 && cupleaza(st[it])) {
dr[node] = it;
st[it] = node;
return 1; // am reusit sa schimb perechea lui st[it] (dr[ st[it] ] = altceva)
}
}
return 0; // altfel nu se poate cupla fara sa micsoram solutia
}
void cuplaj() {
sol = 0; // cate muchii am in cuplaj
bool ready = false;
while (!ready) {
ready = true; // presupun ca sunt gata
for (int i = 1; i <= n; ++i) {
viz[i] = 0; // resetez pt revizitare
}
// parcurg fiecare nod din STANGA
for (int i = 1; i <= n; ++i) {
// daca nodul i din stanga nu e cuplat: dr[i] == 0
// si se poate cuplaL cupleaza(i) != 0
if (!dr[i] && cupleaza(i)) {
sol++; // am crescut solutia
ready = false; // am presupus prost, nu am terminat
}
}
}
g << sol << "\n";
for (int i = 1; i <= n; ++i) {
if (dr[i] != 0) {
g << i << " " << dr[i] << "\n";
}
}
}
int main() {
read_input();
cuplaj();
return 0;
}