Cod sursa(job #1430774)

Utilizator dan.marculetFII MarculetDan dan.marculet Data 8 mai 2015 19:56:14
Problema Cuplaj maxim in graf bipartit Scor 0
Compilator c Status done
Runda Arhiva educationala Marime 2.19 kb
#include <stdio.h>

FILE* fin = fopen("cuplaj.in", "r");
FILE* fout = fopen("cuplaj.out", "w");

int n, N, M, e, ld, dim, drum[100000], nv[20000], c[20000];
int* lv[20000];
bool found, viz[20000];

bool find(int i);
void alterate();

int main() {
	int i, j, x, y;
	int a[100000], b[100000];

// Citire + Preprocesare
	fscanf(fin, "%d %d %d", &N, &M, &e);
	n = N + M;
	for (i = 0; i < e; ++i) {
		fscanf(fin, "%d %d", &x, &y);
		a[i] = x - 1;
		b[i] = y + N - 1;
		++nv[x - 1];
		++nv[y + N - 1];
	}
	for (i = 0; i < n; ++i) {
		lv[i] = new int[nv[i]];
		nv[i] = 0;
	}
	for (i = 0; i < e; ++i) {
		lv[a[i]][nv[a[i]]++] = b[i];
		lv[b[i]][nv[b[i]]++] = a[i];
	}

	/*
	for (i = 0; i < n; ++i) {
		fprintf(fout, "Nodul %d are vecinii: ", i);
		for (j = 0; j < nv[i]; ++j)
			fprintf(fout, "%d ", lv[i][j]);
		fprintf(fout, "\n");
	}
	*/

	for (i = 0; i < n; ++i)
		c[i] = -1;

// Cuplaj maximal - Greedy
	for (i = 0; i < N; ++i) {
		if (c[i] == -1)
		for (j = 0; j < nv[i]; ++j) {
			if (c[lv[i][j]] == -1) {
				++dim;
				c[i] = lv[i][j];
				c[lv[i][j]] = i;
				break;
			}
		}
	}

	/*
	for (i = 0; i < n; ++i)
	if (c[i] + 1)
		fprintf(fout, "%d %d\n", i, c[i]);
	return 0;
	*/

// Cuplaj maximum
	found = true;
	while (found) {
		found = false;
		for (i = 0; i < n; ++i)
		if (c[i] == -1) {
			for (j = 0; j < n; ++j)
				viz[j] = false;
			ld = 0;
			if (find(i) == true)
				found = true;
		}
	}

// Afisare rezultat
	fprintf(fout, "%d\n", dim);
	for (i = 0; i < N; ++i)
	if (c[i] != -1)
		fprintf(fout, "%d %d\n", i + 1, c[i] - N + 1);

	return 0;
}

bool find(int nod) {
	int i, nodp;

	drum[ld++] = nod;
	viz[nod] = true;
	for (i = 0; i < nv[nod]; ++i) {
		nodp = lv[nod][i];
		if (!viz[nodp]) {
			viz[nodp] = true;
			drum[ld++] = nodp;
			if (c[nodp] == -1) {
				alterate();
				return true;
			}
			else if (find(c[nodp]))
				return true;
			--ld;
		}
	}
	--ld;
	return false;
}

void alterate() {
	int i;

	++dim;
	for (i = 0; i < ld - 1; i += 2) {
		c[drum[i]] = drum[i + 1];
		c[drum[i + 1]] = drum[i];
	}
	/*
	for (i = 0; i < ld; ++i) {
		fprintf(fout, "%d ", drum[i]);
	}
	fprintf(fout, "\n");
	*/
}