Cod sursa(job #2635821)

Utilizator irimia_alexIrimia Alex irimia_alex Data 15 iulie 2020 16:42:00
Problema Cuplaj maxim in graf bipartit Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.25 kb
#include <stdio.h>
#include <map>
#include <vector>
#include <queue>
#include <limits.h>

using namespace std;

typedef map<int, int> edge;
typedef vector<map<int, int>> edges;

edges graph;
int L, R, V, E;

FILE* fin, * fout;

bool edgeExists(edges &graph,int u,int v) {
	edge e = graph[u];
	return (e.find(v) != e.end());
}

bool bfs(edges graph, int source, int sink, vector<int>& parent) {
	queue<int> q;
	q.push(source);

	vector<bool> viz(V + 1, false);

	viz[source] = true;
	parent[source] = -1;

	while (!q.empty()) {
		int u = q.front();
		q.pop();
		if (u == sink)
			return true;
		for (auto e : graph[u]) {
			int v = e.first, capacity = e.second;
			if (viz[v] == false && capacity > 0) {
				q.push(v);
				viz[v] = true;
				parent[v] = u;
			}
		}
	}
	return false;
}

void maximumMatching(edges graph, int V, int source, int sink) {
	edges residualGraph(V + 1);
	for (int u = 0;u <= V;++u) {
		for (auto e : graph[u]) {
			int v = e.first, capacity = e.second;
			residualGraph[u][v] = capacity;
			if (!edgeExists(residualGraph,v,u))
				residualGraph[v][u] = 0;
		}
	}

	edges resultGraph(V + 1);

	int max_flow = 0;
	vector<int> parent(V + 1, -1);
	while (bfs(residualGraph, source, sink, parent)) {
		int flow = 1;

		for (int v = sink;v != source;v = parent[v]) {
			int u = parent[v];
			residualGraph[u][v] -= flow;
			residualGraph[v][u] += flow;

		}

		max_flow += flow;
	}

	for (int u = 0;u <= V;++u) {
		for (auto e : graph[u]) {
			int v = e.first, capacity = e.second;
			resultGraph[u][v] = max(0, capacity - residualGraph[u][v]);
		}
	}

	fprintf(fout, "%i\n", max_flow);

	for (int u = 1;u <= L;++u) {
		for (auto e : resultGraph[u]) {
			int v = e.first, flow = e.second;
			if (flow > 0)
				fprintf(fout, "%i %i\n", u, v - L);
		}
	}

}

int main() {
	fin = fopen("cuplaj.in", "r");
	fout = fopen("cuplaj.out", "w");
	
	fscanf(fin, "%i %i %i", &L, &R, &E);

	V = L + R + 1;

	graph.resize(V + 1);

	for (int e = 1;e <= E;++e) {
		int x, y;
		fscanf(fin, "%i %i", &x, &y);

		graph[x][y + L] = 1;

	}

	for (int i = 1;i <= L;++i)
		graph[0][i] = 1;
	for (int i = L + 1;i <= L + R;++i)
		graph[i][V] = 1;

	maximumMatching(graph, V, 0, V);
}