Cod sursa(job #1603473)

Utilizator TeodorCotetCotet Teodor TeodorCotet Data 17 februarie 2016 16:25:39
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.13 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; 

	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(bool findPath = true; findPath ; ) {

		findPath = false;
		used.reset();

		for(int i = 1; i <= nodesLeft; ++i)
			if(pairL[i] == 0)
				findPath |= pairUp(i);
	}

	for(int i = 1; i <= nodesLeft; ++i)
		cuplaj += (pairL[i] > 0);

	/* Incerca sa gaseasca numarul maxim de drumuri care accepta augumentare.
	 	Practic algoritmul e echivalent cu edmonds Karp imbunatatit, doar ca in loc de BFS face DFS si cand ajunge la dstinatie se opreste,
		insa pastreaza nodurile care au fost vizitate, iar apoi cand aplica DFS pentru alt nod (incerca sa.l cupleze) foloseste
		aceeasi configuratie a nodurilor vizitate si mai adauga altele. Le reseteaza doar dupa ce a incercat pentru toate ndourile
		din stanga sa gaseasca un drum. Varianta mai inceata: le reseteaza cand nu poate gasi un drum pentru un nod.

	*/
}

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;
}