Pagini recente » Cod sursa (job #700872) | Cod sursa (job #88625) | Cod sursa (job #3146787) | Cod sursa (job #2860615) | Cod sursa (job #2663808)
#include <fstream>
#include <vector>
#include <bitset>
#define DIM 10010
using namespace std;
vector<int> V[DIM];
int L[DIM], R[DIM], n, m, k, i, ok, x, y, sol;
///L[i] = vecinul din dreapta din cuplaj al jodului i din stanga sau 0 daca nodul i nu e cuplat
///R[i] = vecinul din stanga din cuplaj al jodului i din dreapta sau 0 daca nodul i nu e cuplat
bitset<DIM> U;
int cupleaza(int nod) {
/// incerc sa cuplez pe nod (aflat in stanga si necuplat cu cineva)
if (U[nod] == 1)
return 0;
U[nod] = 1;
/// incerc sa cuplez pe nod direct cu un element din dreapta NECUPLAT inca
int it;
for (int i=0;i<V[nod].size();i++) {
it = V[nod][i];
if (R[it] == 0) {
L[nod] = it;
R[it] = nod;
sol++;
return 1;
}
}
/// daca pe nod din stanga nu il pot cupla direct cu ceva din dreapta
/// pentru ca sunt toti vecinii lui deja cuplati (am testat sta mai sus)
/// caut atunci un vecin (cuplat deci) din dreapta al carui vecin
/// din stanga poate fi cuplat altfel (autoapel al functiei cupleaza)
/// si daca reusesc in cuplez pe nod cu acest vecin
for (int i=0;i<V[nod].size();i++) {
/// sigur R[*it] e nenul
it = V[nod][i];
if (cupleaza(R[it])) {
L[nod] = it;
R[it] = nod;
return 1;
}
}
return 0;
}
int main () {
ifstream fin ("cuplaj.in");
ofstream fout("cuplaj.out");
fin>>n>>m>>k;
for (i=1;i<=k;i++) {
fin>>x>>y;
V[x].push_back(y);
/// indicii din V sunt noduri din multimea stanga
/// iar componentele sunt vecinii din dreapta ai idicelui
}
do {
ok = 0;
U.reset();
for (i=1;i<=n;i++)
if (L[i] == 0) {
ok |= cupleaza(i);
}
} while (ok == 1);
fout<<sol<<"\n";
for (i=1;i<=n;i++)
if (L[i] != 0)
fout<<i<<" "<<L[i]<<"\n";
return 0;
}