Cod sursa(job #434413)

Utilizator MciprianMMciprianM MciprianM Data 5 aprilie 2010 21:06:19
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.94 kb
#include<fstream>
using namespace std;

# define MAXN 20000

int n, m, e, qSize, lSize;
int coada [ MAXN ], from [ MAXN ], leafs [ MAXN ];
bool viz [ MAXN ], cap [ MAXN ] [ MAXN ];

int findPath(){
	int head = 0, i, dad, pathCap, gPathCap = 0;
	bool ok;
	memset ( viz, 0, sizeof ( viz ) );
	memset ( from, -1, sizeof ( from ) );
	qSize = lSize = 0;
	coada [ qSize ++ ] = 1;
	viz [ 1 ] = 1;
	ok = 1;
	while ( head < qSize && ok ){
		for ( i = 1; i <= n && ok ; i ++ )
			if ( cap [ coada [ head ] ] [ i ] > 0 && ! viz [ i ] ){
				coada [ qSize ++ ] = i;
				viz [ i ] = 1;
				from [ i ] = coada [ head ];
				if ( i == n )	leafs [ lSize ++ ] = coada [ head ], qSize --, viz [ n ] = 0;
			}
		head ++;
	}
	
	if ( from [ n ] == -1 )	return 0;
	
	for ( i = 0; i < lSize; i ++ ){
		dad = n;	pathCap = 120000;
		from [ n ] = leafs [ i ];
		while ( from [ dad ] != -1 ){
			if ( cap [ from [ dad ] ] [ dad ] < pathCap )
				pathCap = cap [ from [ dad ] ] [ dad ];
			dad = from [ dad ];
		}
	
		dad = n;
	
		while ( from [ dad ] != -1 ){
			cap [ from [ dad ] ] [ dad ] -= pathCap;
			cap [ dad ] [ from [ dad ] ] += pathCap;
			dad = from [ dad ];
		}
		gPathCap = gPathCap + pathCap;
	}
	return gPathCap;
}

int maxFlow(){
	int d, flow=0;
	while ( 1 ){
		d = findPath ();
		if( d == 0 )	return flow;
		else			flow = flow + d;
	}
}

int main(){
	int x, y, i, j, flow = 0, np, mp;
	ifstream f ( "cuplaj.in" );
	f >> np >> mp >> e;
	for ( i = 0; i < e; i ++ ){
		f >> x >> y;
		cap [ x + 1 ] [ y + np + 1 ] = 1;
	}
	n = np + mp + 2;
	for ( i = 1 ; i <= np; i ++ )
		cap [ 1 ] [ i + 1 ] = 1;
	for ( i = 1 ; i <= mp; i ++ )
		cap [ i + np + 1 ] [ n ] = 1;
	f.close();
	flow = maxFlow ();
	ofstream g ( "cuplaj.out" );
	g << flow << '\n';
	for ( i = 1; i <= mp; i++ )
		for ( j = 1; j <= np; j ++ )
			if ( cap [ i + np + 1 ] [ j + 1 ] ){
				g << j << ' ' << i << '\n';
				break;
			}
	g.close();
	return 0;
}