Pagini recente » Scrie articole | Cod sursa (job #3270744) | Rating Andrei Parau (andreiparau) | Monitorul de evaluare | Cod sursa (job #2085993)
#include <fstream>
#include <iostream>
#include <vector>
#include <cstring>
#define NMax 10010
using namespace std;
vector<int> G[NMax];
int leftCardinal, rightCardinal, edgesCardinal;
int L[NMax], R[NMax];
bool viz[NMax];
bool HopcroftKarp(const int &leftNode)
{
if (viz[leftNode])
{
return false;
}
viz[leftNode] = true;
for (vector<int>::iterator it = G[leftNode].begin(); it != G[leftNode].end(); ++it) // *it este un vecin de-al lui leftNode din dreapta lui
{
if (L[*it] == 0) // daca am gasit un vecin *it din dreapta lui leftNode care nu e cuplat cu nimeni din stanga atunci cuplam leftNode cu *it
{
R[leftNode] = *it;
L[*it] = leftNode;
return true; // returnam true pentru ca am putut imbunatati cuplajul folosind un lant alternant, format din muchia de la leftNode la *it
}
}
// daca am ajuns aici inseamna ca toti vecinii din dreatpa lui leftNode sunt cuplati cu cineva din stanga si vom incerca sa gasim un lant alternant
// trecand prin aceste noduri
for (vector<int>::iterator it = G[leftNode].begin(); it != G[leftNode].end(); ++it)
{
if (HopcroftKarp(L[*it]))
{
// daca am reusit sa cuplam nodul L[*it], care era candva cuplat cu *it atunci inseamna ca *it a ramas liber si il putem cupla cu leftNode
R[leftNode] = *it;
L[*it] = leftNode;
return true;
}
}
return false;
}
int main()
{
ifstream f("cuplaj.in");
f >> leftCardinal >> rightCardinal >> edgesCardinal;
for (int i = 1; i <= edgesCardinal; ++i)
{
int x, y;
f >> x >> y;
G[x].push_back(y); // x este un nod din stanga, iar G[x] este lista cu toti vecinii din dreapta
}
f.close();
bool done = false;
while (!done)
{
done = true;
memset(viz, 0, sizeof(viz));
for (int i = 1; i <= leftCardinal; ++i)
{
if (R[i] == 0)
{
if (HopcroftKarp(i)) // daca am imbunatit cuplajul folosind un lant alternant care incepe din nodul i din partea stanga
{
done = false;
}
}
}
}
ofstream g("cuplaj.out");
int matchingCardinal = 0;
for (int i = 1; i <= leftCardinal; ++i)
{
if (R[i] != 0)
{
++matchingCardinal;
}
}
g << matchingCardinal << "\n";
for (int i = 1; i <= leftCardinal; ++i)
{
if (R[i] != 0)
{
g << i << " " << R[i] << "\n";
}
}
g.close();
return 0;
}