Pagini recente » Cod sursa (job #2468994) | Cod sursa (job #1419558) | Cod sursa (job #3123689) | Cod sursa (job #2889695) | Cod sursa (job #2961913)
//
// Created by Carla on 1/7/2023.
//
#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;
}