Cod sursa(job #554412)

Utilizator feelshiftFeelshift feelshift Data 14 martie 2011 20:33:47
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.58 kb
// http://infoarena.ro/problema/cuplaj
#include <fstream>
#include <vector>
#include <queue>
using namespace std;

#define maxSize 10002
#define oo 0x3f3f3f3f
#define source 0
#define destination 10001

ifstream in("cuplaj.in");
ofstream out("cuplaj.out");

bool visit[maxSize];
int father[maxSize];
int capacity[maxSize][maxSize];
int currentFlow[maxSize][maxSize];
vector<int> graph[maxSize];

bool breadthFirst();

int main() {
	int firstSet,secondSet,edges;
	in >> firstSet >> secondSet >> edges;

	int from,to;
	for(int i=1;i<=edges;i++) {
		in >> from >> to;
		to += firstSet;

		capacity[from][to] = 1;
		//capacity[to][from] = 1;

		graph[from].push_back(to);
		graph[to].push_back(from);
	}

	for(int i=1;i<=firstSet;i++) {
		graph[source].push_back(i);
		//graph[i].push_back(source);

		capacity[source][i] = 1;
		//capacity[i][source] = 1;
	}

	for(int i=firstSet+1;i<=firstSet+secondSet;i++) {
		graph[i].push_back(destination);
		graph[destination].push_back(i);

		capacity[i][destination] = 1;
		//capacity[destination][i] = 1;
	}

	int maxFlow = 0;
	vector<int>::iterator it,end;

	while(breadthFirst()) {
		end = graph[destination].end();
		for(it=graph[destination].begin();it!=end;++it)
			if(visit[*it] && capacity[*it][destination] != currentFlow[*it][destination]) {
				int node = *it;
				int minFlow = oo;

				father[destination] = node;

				for(node=destination;node!=source;node=father[node])
					minFlow = min(minFlow,capacity[father[node]][node] - currentFlow[father[node]][node]);

				if(minFlow) {
					for(node=destination;node!=source;node=father[node]) {
						currentFlow[father[node]][node] += minFlow;
						currentFlow[node][father[node]] -= minFlow;
					}

					maxFlow += minFlow;
				}
			}
	}

	out << maxFlow << "\n";

	for(int i=1;i<=firstSet+secondSet;i++) {
		end = graph[i].end();
		for(it=graph[i].begin();it!=end;++it)
			if(currentFlow[i][*it] == 1 && *it != destination)
				out << i << " " << *it - firstSet << "\n";
	}

	return (0);
}

bool breadthFirst() {
	memset(visit,false,sizeof(visit));
	visit[source] = true;

	int node;
	vector<int>::iterator it,end;

	queue<int> myQueue;
	myQueue.push(source);

	while(!myQueue.empty()) {
		node = myQueue.front();
		myQueue.pop();

		if(node == destination)
			continue;

		end = graph[node].end();
		for(it=graph[node].begin();it!=end;++it)
			if(!visit[*it] && currentFlow[node][*it] < capacity[node][*it] ) {
				visit[*it] = true;
				father[*it] = node;
				myQueue.push(*it);
			}
	}

	return visit[destination];
}