Cod sursa(job #1603432)

Utilizator TeodorCotetCotet Teodor TeodorCotet Data 17 februarie 2016 15:39:42
Problema Cuplaj maxim in graf bipartit Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 1.78 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <bitset>

using namespace std;

ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");

const int NMAX = 10000;
const int MMAX = 10000;

int nodesLeft ; int nodesRight;  int m;

vector< vector<int> > g(NMAX + 1, vector<int>(0));

bitset<NMAX + 1> used;

int pairL[NMAX + 1]; int pairR[NMAX + 1]; 

int cuplaj;

void read() {

	fin >> nodesLeft >> nodesRight >> m;
	for(int i = 1; i <= m ; ++i) {

		int x; int y;
		fin >> x >> y;
		g[x].push_back(y);
	}
}

bool pairUp(int node) {

	if(used[node] == true) return false; //a mai fost vizitat

	used[node] = true;

	for(int x : g[node]) 
		if(pairR[x] == 0) { //pot sa.l imperechez cu un vecin de.al lui

			pairL[node] = x;
			pairR[x] = node;
			return true;
		}
	//daca toti vecinii sunt imperecheati, incerc sa decuplex unul, si sa.i cuplez perechea cu altcineva

	for(int x : g[node]) 
		if(pairUp(pairR[x])) { //daca pot sa.i cuplez perechea perechii nodului meu node 

			pairL[node] = x;
			pairR[x] = node;
			return true;
		}

	return false;
}

void solve() {

	for(int i = 1; i <= nodesLeft; ++i)
		if(pairL[i] == 0)  {//daca nu e imperecheat
			used.reset(); //fac o parcurgere
			if(pairUp(i))  //incearca sa.l imperechezi aka sa gasesc un drum la destinatie
				cuplaj++;
			else {
				//practic incerc sa fac un nou BFS doar atunci cand nu mai pot sa gasesc un drum pentru nodul i
				//used.reset(); //practic marchez tote nodurile ca nevizitate
				//cuplaj += pairUp(i); //caut un drum 
			}
		}
}

void print() {

	fout << cuplaj << '\n'; 

	for(int i = 1; i <= nodesLeft ; ++i) 
		if(pairL[i])
			fout << i << " " << pairL[i] << '\n'; 
}

int main() {

	read();

	solve();

	print();

	return 0;
}