Cod sursa(job #2208849)

Utilizator MihaiAntonMihai Anton MihaiAnton Data 31 mai 2018 20:08:09
Problema Cuplaj maxim in graf bipartit Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 3.23 kb
#include <fstream>
#include <vector>
#include <list>
#include <queue>

#define INF 0x7fffffff

using namespace std;

struct graph {

	int vertexCount;
	int edgeCount;

	list<int>* adjList;

	list<int> setU;
	list<int> setV;

	int* dist;

	int* matchOfU;
	int* matchOfV;
};

void separateBiparts(graph& g) {

	int* viz = new int[g.vertexCount + 1];
	//memset(viz, false, g.vertexCount + 1);
	int* part = new int[g.vertexCount + 1];
	//memset(part, 0, g.vertexCount + 1);

	for (int i = 0; i <= g.vertexCount; i++) {
		viz[i] = false;
		part[i] = 0;
	}

	queue<int> q;
	q.push(1);
	part[1] = 1;

	g.setU.push_back(1);

	while (!q.empty()) {

		int crt = q.front();
		q.pop();
		viz[crt] = true;

		for (auto elem : g.adjList[crt]) {

			if (!viz[elem]) {
				viz[elem] = true;
				q.push(elem);
				part[elem] = part[crt] == 1 ? 2 : 1;

				if (part[elem] == 1)
					g.setU.push_back(elem);
				else
					g.setV.push_back(elem);
			}
		}
	}
	delete part;
	delete viz;
}

void readGraph(graph& g, ifstream& in) {

	int a, b;
	in >> a >> b >> g.edgeCount;
	g.vertexCount = a + b;
	g.adjList = new list<int>[g.vertexCount + 1];

	for (int i = 1; i <= g.edgeCount; i++) {
		int v1, v2;
		in >> v1 >> v2;
		v2 += a;
		
		g.adjList[v1].push_back(v2);
		g.adjList[v2].push_back(v1);
	}

	separateBiparts(g);

	for (auto i : g.setU) {
		g.adjList[0].push_back(i);
	}

	g.dist = new int[g.vertexCount + 1];
	g.matchOfU = new int[g.vertexCount + 1];
	g.matchOfV = new int[g.vertexCount + 1];

	return;
}

bool bfs(graph& g) {

	queue<int> bfsQ;

	for (auto vertex : g.setU) {
		if (g.matchOfU[vertex] == 0) {
			g.dist[vertex] = 0;
			bfsQ.push(vertex);
		}
		else
			g.dist[vertex] = INF;
	}
	g.dist[0] = INF;

	while (!bfsQ.empty()) {

		int crtVert = bfsQ.front();
		bfsQ.pop();

		if(g.dist[crtVert] < g.dist[0])
			for (auto vertex : g.adjList[crtVert]) {

				if (g.dist[g.matchOfV[vertex]] == INF) {
					g.dist[g.matchOfV[vertex]] = g.dist[crtVert] + 1;
					bfsQ.push(g.matchOfV[vertex]);
				}
			}
	}

	return g.dist[0] != INF;	
}

bool dfs(graph& g, int vertex) {

	if (vertex != 0) {

		for (auto adjVert : g.adjList[vertex]) {

			if (g.dist[g.matchOfV[adjVert]] == (g.dist[vertex] + 1)) {

				if (dfs(g, g.matchOfV[adjVert])) {

					g.matchOfV[adjVert] = vertex;
					g.matchOfU[vertex] = adjVert;
					return true;
				}

			}
		}
		g.dist[vertex] = INF;
		return false;
	}
	return true;
}

int hopcroftKarp(graph& g) {

	for (int elem = 0; elem <= g.vertexCount; elem++) {
		g.matchOfU[elem] = 0;
	}

	for (int elem = 0; elem <= g.vertexCount; elem++) {
		g.matchOfV[elem] = 0;
	}


	int matchings = 0;

	while (bfs(g)) {

		for (auto vertex : g.setU) {
			if (g.matchOfU[vertex] == 0 && dfs(g, vertex))
				matchings++;
		}
	}
	return matchings;
}














int main() {
	
	graph g;

	ifstream in("cuplaj.in");
	readGraph(g, in);
	in.close();

	int matchings = hopcroftKarp(g);

	ofstream out("cuplaj.out");
	out << matchings << "\n";
	for (auto elem : g.setU) {
		if (g.matchOfU[elem] != 0)
			out << elem << " " << g.matchOfU[elem]- g.setU.size() << "\n";
	}
	out.close();

	return 0;
}