Cod sursa(job #429681)

Utilizator slayer4uVictor Popescu slayer4u Data 30 martie 2010 13:05:43
Problema Cuplaj maxim in graf bipartit Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.92 kb
#include <cstdio>
#include <vector>
using namespace std;

vector <pair <int, int> > rez;

#define NMAX 10000
#define inf 2147000000

long graf[NMAX][NMAX], flux[NMAX][NMAX], este_drum, n, m, e, a, b, minmin, v[NMAX], viz;

struct lol
{
	long nod, tata, minim;
};
lol queue[NMAX];

void BFS()
{
	++viz;
	long beg = 1, end = 1;
	queue[beg].tata = -1;
	queue[beg].nod = 0;
	queue[beg].minim = inf;
	v[0] = viz;

	while (beg <= end)
	{
		long nod = queue[beg].nod;
		for (long i = 1; i <= n + m + 1; ++i)
		{
			if (graf[nod][i] || graf[i][nod])
			{
				long reziduu = graf[nod][i] - flux[nod][i];
				if (v[i] != viz && reziduu)
				{
					v[i] = viz;
					++end;
					queue[end].tata = beg;
					queue[end].nod = i;
					queue[end].minim = queue[beg].minim < reziduu ? queue[beg].minim : reziduu;
					if (i == n + m + 1)
					{
						beg = inf - 1;
						break;
					}
				}
			}
		}
		++beg;
	}
	
	minmin = queue[end].minim;
	if (beg == inf)
	{
		este_drum = 1;
		while (queue[end].tata != -1)
		{
			flux[queue[queue[end].tata].nod][queue[end].nod] += minmin;
			flux[queue[end].nod][queue[queue[end].tata].nod] -= minmin;
			end = queue[end].tata;
		}
	}
	else
	{
		este_drum = 0;
	}
}

int main()
{
	freopen ("cuplaj.in", "rt", stdin);
	freopen ("cuplaj.out", "wt", stdout);
	
	scanf("%ld %ld %ld", &n, &m, &e);
	for (long i = 1; i <= e; ++i)
	{
		scanf("%ld %ld", &a, &b);
		graf[a][n + b] = 1;
	}

	for (long i = 1; i <= n; ++i)
		graf[0][i] = 1;
	for (long i = 1; i <= m; ++i)
		graf[n + i][n + m + 1] = 1;

	este_drum = 1;
	while (este_drum)
	{
		este_drum = 0;
		BFS();
	}

	for (long i = 1; i <= n + m; ++i)
		for (long j = 1; j <= n + m; ++j)
			if (flux[i][j] > 0)
				rez.push_back(make_pair(i, j - n));
	
	printf("%ld\n", rez.size());
	for (long i = 0; i < rez.size(); ++i)
	{
		printf("%ld %ld\n", rez[i].first, rez[i].second);
	}

	return 0;
}