Pagini recente » Cod sursa (job #1380484) | Cod sursa (job #1009417) | Cod sursa (job #166947) | Cod sursa (job #1203589) | Cod sursa (job #2961045)
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <cstring>
#include <fstream>
using namespace std;
ifstream in("cuplaj.in");
ofstream out("cuplaj.out");
///l -> vect de adiacenta
vector<int> l[20001];
///viz -> vector de vizitate
///stim ca problemele de cuplaj se rezolva pe un graf bipartit deci vom avea 2 vectori: gr1 -> partitia din stanga si gr2 -> partitia din dreapta
int viz[20001], gr1[20001], gr2[20001] ;
///functia care realizeaza cuplajul celor doua partitii
int matching(int val)
{
///daca nodul nu e vizitat mergem mai departe
if(viz[val])
return 0;
///marchez nodul ca vizitat
viz[val] = 1;
///iterez prin lista de adiacenta a acestuia si caut un vecin din a doua partitie care nu are pereche si ii adaug reciproc pe fiecare
///vectorul celeilalte persoane, iar daca gasesc o astfel de pereche pe care reusesc sa o cuplez intrerup functia => succes
for(int i = 0; i < l[val].size(); i++)
if(!gr2[l[val][i]])
{
gr1[val] = l[val][i];
gr2[l[val][i]] = val;
return 1;
}
///daca am trecut de comanda anterioara fara sa mai gasesc persoane necuplate pt valoarea mea, atunci ma uit daca pot cupla persoanele
///din cealalta partitie cu alte persoane, daca gasesc ies din functie => succes
for(int i = 0; i < l[val].size(); i++)
if(matching(gr2[l[val][i]]))
{
gr1[val] = l[val][i];
gr2[l[val][i]] = val;
return 1;
}
///n-am gasit nimic, nu sunt petitor bun => esec(nu mai pot cupla persoane)
return 0;
}
int main()
{
int n, m, e, st, fin, ok = 1, match = 0;
///citim cadinalele celor doua multimi si nr de legaturi dintre ele
in>>n>>m>>e;
///citim legaturile
///pentru a avea flux -> legam nodurile doar din stanga in dreapta
for(int i = 1; i <= e; i++)
{
in>>st>>fin;
l[st].push_back(fin);
}
///cat timp reusim sa efectuam cuplaje parcurgem aceasta bucla while cu ajutorul careia
///cautam nodurile care nu au pereche si care mai pot forma o pereche
while(ok)
{
ok = 0;
///resetam vectorul de vizitate
memset(viz, 0, sizeof(viz));
for(int i = 1; i <= n; i++)
if(!gr1[i])
ok |= matching(i);
}
///numaram cate cuplaje s-au format, contorizand cate persoane din prima partitie au pereche
for(int i = 1; i <= n; i++)
if(gr1[i])
match += 1;
out<<match<<"\n";
///afisam perechile cautand persoanele din prima partitie care au pereche si afisand valoarea perechii lor, memorata in vector
for(int i = 1; i <= n; i++)
if(gr1[i])
out<<i<<" "<<gr1[i]<<"\n";
return 0;
}