Cod sursa(job #551873)

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

using namespace std;
struct vertex
{
	int y, capacity, flux;
	vertex *next, *op;
} *G[N_MAX];
int N, M, countVertex, sink;
inline void Add( int x, int y )
{
	vertex *p=new vertex, *q=new vertex;
	p->y=y;			q->y=x;
	p->capacity=1;	q->capacity=0;
	p->flux=0;		q->flux=0;
	p->next=G[x];	q->next=G[y];
	G[x]=p;			G[y]=q;
	G[x]->op=G[y];	G[y]->op=G[x];
}
bool findPath()
{
	int x;
	vertex *p;
	queue< int > Q;
	vector< vertex* > f( countVertex+1 );
	for( Q.push(source); !Q.empty() && NULL == f[sink]; )
	{
		x=Q.front(); Q.pop();
		for( p=G[x]; NULL != p; p=p->next )
		{
			if( source == p->y )
				continue;
			if( NULL == f[p->y] && p->capacity > p->flux )
			{
				f[p->y]=p;
				if( sink == p->y )
					break;
				Q.push(p->y);
			}
		}
	}
	if( NULL == f[sink] )
		return false;
	for( p=f[sink]; p; p=f[p->op->y] )
		++p->flux, --p->op->flux;
	return true;
}
int main()
{
	int E, x, y, maxMatch;
	vertex *p;
	ifstream in( "cuplaj.in" );
	for( in>>N>>M>>E; E; --E )
	{
		in>>x>>y;
		Add( x, y+N );
	}
	countVertex=sink=N+M+1;
	for( x=1; x <= N; ++x )
		if( G[x] )
		{
			Add( source, x );
		}
	for( y=N+1, M+=N; y <= M; ++y )
		if( G[y] )
		{
			Add( y, sink );
		}
	for( maxMatch=0; findPath(); ++maxMatch );
	ofstream out( "cuplaj.out" );
	out<<maxMatch<<'\n';
	for( x=1; maxMatch && x <= N; ++x )
	{
		for( p=G[x]; p; p=p->next )
			if( p->flux > 0 )
			{
				out<<x<<' '<<(p->y-N)<<'\n';
				--maxMatch;
			}
	}
	return EXIT_SUCCESS;
}