Pagini recente » Cod sursa (job #2738257) | Cod sursa (job #626819) | Cod sursa (job #1972948) | Cod sursa (job #1738744) | Cod sursa (job #2692387)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
/// sursa adaptata dupa cea referita la indicatii
ifstream f("cuplaj.in");
ofstream g("cuplaj.out");
vector <int> * lv;
int l_card, r_card;
int n, m;
int * match;
bool * visited;
bool find_aug_path(int l_node){
visited[l_node] = 1;
/// caz de baza al cand nodul din dreapta poate fi cuplat direct cu nodul din stanga necuplat
for(int i = 0; i < lv[l_node].size(); i++){
int r_node = lv[l_node][i];
if(!match[r_node]){
match[l_node] = r_node;
match[r_node] = l_node;
return true;
}
}
/// daca nu am noduri cu care sa pot cupla direct nodul curent, caut urmatoarele 2 muchii alternante
/// de pe drumul de augumentat
for(int i = 0; i < lv[l_node].size(); i++){
int r_node = lv[l_node][i];
int next_l_node = match[r_node]; /// garantat va fi /= 0 datorita for ului de mai sus
/// apelez recursiv find_aug_path; daca la finalul stivei apelului se ajunge
/// la cazul de baza, atribuirile facute refac cuplajele corespunzatoare de pe aug_path
/// array ul visited ma ajuta sa nu ciclez
if(!visited[next_l_node] && find_aug_path(next_l_node)){
match[l_node] = r_node;
match[r_node] = l_node;
return true;
}
}
/// nu am gasit nici un augumenting path
return false;
}
void Hopcroft(){
bool aug_path_found;
/// execut cat timp la fiecare pas gasesc cel putin un augumenting path (actualizez cuplajul)
do{
aug_path_found = 0;
for(int l_node = 1; l_node <= l_card; l_node++)
if(!match[l_node]){
for(int i = 1; i <= l_card; i++)
visited[i] = 0;
aug_path_found |= find_aug_path(l_node);
}
}
while(!aug_path_found);
}
int main(){
f >> l_card >> r_card >> m;
n = l_card + r_card;
lv = new vector <int> [n + 1];
match = new int [n + 1];
visited = new bool [l_card + 1];
for(int i = 1; i <= n; i++)
match[i] = 0;
int x, y;
for(int i = 0; i < m; i++){
f >> x >> y;
lv[x].push_back(y + l_card);
}
Hopcroft();
int max_matching = 0;
for(int l_node = 1; l_node <= l_card; l_node++)
if(match[l_node])
max_matching += 1;
g << max_matching << '\n';
for(int l_node = 1; l_node <= l_card; l_node++){
if(match[l_node])
g << l_node << " " << match[l_node] - l_card << '\n';
}
return 0;
}