Cod sursa(job #1237790)

Utilizator sorin2kSorin Nutu sorin2k Data 4 octombrie 2014 20:08:59
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.56 kb
#include<iostream>
#include<vector>
using namespace std;

vector<int> adj[10001];
// l[i] = ce nod din dreapta e pereche cu nodul i din stanga
// r[i] = ce nod din stanga e pereche cu nodul i din dreapta
int l[10001], r[10001];
// used[i] = nodul a fost folosit in iteratia curenta
bool used[10001];
int n, m, e;

// Nodul start e din partea stanga si se incearca cuplarea acestuia cu un nod
// din dreapta. Daca se gaseste un nod in partea dreapta liber, se cupleaza cu el.
// Daca nu, se incearca eliminarea muchiei dintre acel nod din dreapta si perechea lui
// si se incearca cuplarea perechii nodului din dreapta cu un alt nod din dreapta.
// Procedeul se repeta recursiv.
bool cupleaza(int start) {
	if(used[start]) return false;
	used[start] = true;
	for(vector<int>::iterator it = adj[start].begin(); it != adj[start].end(); ++it) {
		if(r[*it] == 0 || cupleaza(r[*it])) {
			l[start] = *it;
			r[*it] = start;
			return true;
		}
	}
	return false;
}

int main() {
	freopen("cuplaj.in", "r", stdin);
	freopen("cuplaj.out", "w", stdout);
	int i, u, v, cuplaj = 0;
	bool ok = false;
	cin >> n >> m >> e;
	for(i = 0; i < e; i++) {
		cin >> u >> v;
		adj[u].push_back(v);
	}
	while(!ok) {
		ok = true;
		for(i = 1; i <= n; i++) {
			used[i] = false;
		}
		for(i = 1; i <= n; i++) {
			// daca un nod e liber si reusesc sa il cuplez
			if(l[i] == 0 && cupleaza(i)) {
				ok = false;
				cuplaj++;
			}
		}
	}
	cout << cuplaj << "\n";
	for(i = 1; i <= n; i++) {
		if(l[i]) {
			cout << i << " " << l[i] << "\n";
		}
	}
	return 0;
}