Cod sursa(job #2535056)

Utilizator radustn92Radu Stancu radustn92 Data 31 ianuarie 2020 13:07:21
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.76 kb
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;

const int NMAX = 20505;
const int INF = 0x3f3f3f3f;
int N, M, E;

vector<int> G[NMAX];
int L[NMAX], R[NMAX];

void read() {
	scanf("%d%d%d", &N, &M, &E);
	int x, y;
	for (int edgeIdx = 0; edgeIdx < E; edgeIdx++) {
		scanf("%d%d", &x, &y);
		G[x].push_back(y + N);
	}
}

bool bfs(vector<int>& shortestDist) {
	shortestDist.assign(N + 1, INF);
	queue<int> Q;
	for (int node = 1; node <= N; node++) {
		if (!L[node]) {
			shortestDist[node] = 0;
			Q.push(node);
		}
	}

	bool foundImprovement = false;
	while (!Q.empty()) {
		int node = Q.front();
		Q.pop();

		for (auto& nodeRight : G[node]) {
			if (!R[nodeRight]) {
				foundImprovement = true;
			}

			if (R[nodeRight] && shortestDist[R[nodeRight]] == INF) {
				shortestDist[R[nodeRight]] = shortestDist[node] + 1;
				Q.push(R[nodeRight]);
			}
		}
	}

	return foundImprovement;
}

bool dfs(int node, vector<bool>& visited) {
	if (visited[node]) {
		return false;
	}

	visited[node] = true;
	for (auto& nodeRight : G[node]) {
		if (!R[nodeRight] || dfs(R[nodeRight], visited)) {
			L[node] = nodeRight;
			R[nodeRight] = node;
			return true;
		}
	}

	return false;
}

void solve() {
	bool foundImprovement = true;
	int matchSize = 0;
	vector<bool> visited;
	while (foundImprovement) {
		foundImprovement = false;
		visited.assign(N + 1, false);
		for (int node = 1; node <= N; node++) {
			if (!L[node] && dfs(node, visited)) {
				foundImprovement = true;
				matchSize++;
			}
		}
	}

	printf("%d\n", matchSize);
	for (int leftNode = 1; leftNode <= N; leftNode++) {
		if (L[leftNode]) {
			printf("%d %d\n", leftNode, L[leftNode] - N);
		}
	}
}

int main() {
	freopen("cuplaj.in", "r", stdin);
	freopen("cuplaj.out", "w", stdout);

	read();
	solve();
	return 0;
}