Cod sursa(job #551797)

Utilizator BitOneSAlexandru BitOne Data 11 martie 2011 09:41:56
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.01 kb
#include <queue>
#include <vector>
#include <fstream>
#include <cstdlib>
#define N_MAX 20011 
#define oo 1<<20
#define source 0

using namespace std;
struct vertex
{
	int y, opy, capacity, flux;
	vertex( int _y, int _capacity, int _flux ) : y(_y), capacity(_capacity), flux(_flux) {}
};
int countVertex, sink;
vector< vertex > G[N_MAX];
vector< vertex >::const_iterator it, iend;
bool findPath()
{
	int x, y;
	queue< int > Q;
	vector< int > f(countVertex+1, -1 ), fit( countVertex+1, -1 );
	f[source]=-2;
	for( Q.push(source); !Q.empty() && -1 == f[sink]; )
	{
		x=Q.front(); Q.pop();
		for( y=0, it=G[x].begin(), iend=G[x].end(); it < iend; ++it, ++y )
			if( -1 == f[it->y] && it->capacity > it->flux )
			{
				f[it->y]=x;
				fit[it->y]=y;
				if( sink == it->y )
					break;
				Q.push(it->y);
			}
	}
	if( -1 == f[sink] )
		return false;
	for( x=sink; -2 != f[x]; x=f[x] )
	{
		G[f[x]][fit[x]].flux+=1;
		G[x][G[f[x]][fit[x]].opy].flux-=1;
	}
	return true;
}
int main( void )
{
	int N, M, E, x, y;
	ifstream in( "cuplaj.in" );
	for( in>>N>>M>>E; E; --E )
	{
		in>>x>>y;
		y+=N;
		G[x].push_back( vertex( y, 1, 0 ) );
		G[y].push_back( vertex( x, 0, 0 ) );
		G[x].back().opy=G[y].size()-1;
		G[y].back().opy=G[x].size()-1;
	}
	countVertex=sink=N+M+1;
	for( x=1; x <= N; ++x )
		if( !G[x].empty() )
		{
			G[source].push_back( vertex( x, 1, 0 ) );
			G[x].push_back( vertex( source, 0, 0 ) );
			G[source].back().opy=G[x].size()-1;
			G[x].back().opy=G[source].size()-1;
		}
	for( y=N+1, M+=N; y <= M; ++y )
		if( !G[y].empty() )
		{
			G[y].push_back( vertex( sink, 1, 0 ) );
			G[sink].push_back( vertex( y, 0, 0 ) );
			G[y].back().opy=G[sink].size()-1;
			G[sink].back().opy=G[y].size()-1;
		}
	for( x=0; findPath(); ++x );
	ofstream out( "cuplaj.out" );
	out<<x<<'\n';
	for( y=1; x && y <= N; ++y )
	{
		for( it=G[y].begin(), iend=G[y].end(); it < iend; ++it )
			if( it->flux > 0 )
			{
				out<<y<<' '<<(it->y-N)<<'\n';
				--x;
			}
	}
	return EXIT_SUCCESS;
}