Cod sursa(job #711145)

Utilizator mika17Mihai Alex Ionescu mika17 Data 11 martie 2012 14:27:00
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.83 kb
#include <vector>
#include <fstream>
#include <limits>
#include <algorithm>
using namespace std;

vector< vector<int > > GL, GR;
vector <int> lpair,rpair;
bool dfs();
int main() {

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

	int le,ri,e;
	in >> le >> ri >> e;
	
	GL.resize(le); GR.resize(ri);
	
	for(int x,y; e--;) {
		in >> x >> y;
		--x; --y;
		GL[x].push_back(y);
		GR[y].push_back(x);
	}

	lpair.assign(le,numeric_limits<int>::max()); rpair.assign(ri,numeric_limits<int>::max());
	
	while(dfs());
	
	out << lpair.size() - count(lpair.begin(),lpair.end(),numeric_limits<int>::max()) << endl;
	for(vector<int> :: iterator i = lpair.begin(); i != lpair.end(); ++i) {
		if(*i != numeric_limits<int>::max())
			out << i - lpair.begin() + 1 << ' ' << *i + 1 << endl;
	}
	return 0;
}

vector<bool> visl,visr;
bool dfs_r(int k,bool left) //we're either on the left or right side
{
	if(left) //stanga
	{
		visl[k] = true;
		for(vector<int>::iterator i = GL[k].begin() ; i != GL[k].end(); ++i)
			if(!visr[*i] && rpair[*i] != k) //edge must be free
			{
				if(dfs_r(*i,false))
				{
					lpair[k] = *i, rpair[*i] = k;
					return true;
				}
			}
		return false;
	}
	else //dreapta
	{
		visr[k] = true;
		for(vector<int>::iterator i = GR[k].begin() ; i != GR[k].end(); ++i)
			if(!visl[*i] && lpair[*i] == k) //edge must be occupied
			{
				if(dfs_r(*i,true))
				{
					//rpair[k] = *i, lpair[*i] = k;
					return true;
				}
			}
		if(rpair[k] == numeric_limits<int>::max())
			return true;
		else return false;
	}
}

bool dfs() {
	
	bool found = false;

	visl.assign(lpair.size(),false);
	visr.assign(rpair.size(),false);
	for(int i = 0; i < (int)lpair.size(); ++i)
		if(lpair[i] == numeric_limits<int>::max())
		{
			if(dfs_r(i,true))
				found = true;
		}
	return found;
}