Cod sursa(job #345496)

Utilizator chris_11Botau Cristian chris_11 Data 3 septembrie 2009 13:22:42
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.38 kb
#include <cstdio>
#include <vector>

using namespace std;

#define INPUT_F "cuplaj.in"
#define OUTPUT_F "cuplaj.out"

#define MAX_N 10100
#define pb push_back

#define FORI(i, s, e) for(int i = (s); i <= (e); i++)
#define FOR(i, V) for (vector<int>::iterator i = (V).begin(); i != (V).end(); i++)

#define hookup(x, y) l[(x)] = (y), r[(y)] = (x)

vector<int> G[MAX_N];
int N, M;
int l[MAX_N], r[MAX_N], viz[MAX_N];

void read_data(FILE *fin)
{
	int edges;
	fscanf(fin, "%d %d %d", &N, &M, &edges);

	for (int x, y, i = 0; i < edges; ++i)
	{
		fscanf(fin, "%d %d", &x, &y);
		G[x].pb(y);
	}
}

int pairup(int v)
{
	if (viz[v]) return 0;
	viz[v] = 1;

	FOR(i, G[v])
		if (!r[*i]) {
			hookup(v, *i);
			return 1;
		}

	FOR(i, G[v])
		if (pairup(r[*i])) {
			hookup(v, *i);
			return 1;
		}

	return 0;
}

void bipartiteMatching()
{
	int changed;
	do
	{
		changed = 0;
		memset(viz, 0, sizeof(viz));
		FORI(i, 1, N)
			if (!l[i])
				changed |= pairup(i);
	} while (changed);
}

void print_data(FILE *fout)
{
	int size = 0;
	FORI(i, 1, N)
		if (l[i])
			size++;

	fprintf(fout, "%d\n", size);
	FORI(i, 1, N) 
		if (l[i])
			fprintf(fout, "%d %d\n", i, l[i]);
}

int main()
{
	FILE *fin = fopen(INPUT_F, "r"), *fout = fopen(OUTPUT_F, "w");
	read_data(fin);
	bipartiteMatching();
	print_data(fout);
	fclose(fin), fclose(fout);
}