Cod sursa(job #1596459)

Utilizator tamionvTamio Vesa Nakajima tamionv Data 11 februarie 2016 00:21:48
Problema Cuplaj maxim in graf bipartit Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.46 kb
#include <fstream>
#include <algorithm>
#include <vector>
using namespace std;

constexpr int maxn = 10010;

class try_to_repair_class{
	const vector<vector<int>>& graf;
	vector<int>& right, left;
	vector<bool>& tried;
public:
	try_to_repair_class(const vector<vector<int>>& g, vector<int>& r, vector<int>& l, vector<bool>& t):
		graf(g), right(r), left(l), tried(t){}
	bool operator()(const int x){
		if(tried[x]){
			return false; }
		tried[x] = true;
		for(const auto y : graf[x]){
			if(left[y] == -1){
				right[x] = y;
				left[y] = x;
				return true; } }
		for(const auto y : graf[x]){
			if((*this)(left[y])){
				right[x] = y;
				left[y] = x;
				return true; } }
		return false; } };

int main(){
	ifstream f("cuplaj.in");
	ofstream g("cuplaj.out");
	int n, m, e;

	f >> n >> m >> e;

	static vector<vector<int>> graf(n);
	for(int i = 0, a, b; i < e; ++i){
		f >> a >> b;
		graf[a-1].push_back(b-1); }

	static vector<int> right(n, -1), left(m, -1);
	static vector<bool> tried(n, false);
	
	try_to_repair_class try_to_repair(graf, right, left, tried);

	for(bool changed = true; changed; ){
		changed = false;
		fill(begin(tried), end(tried), false);
		for(int i = 0; i < n; ++i){
			if(right[i] == -1){
				changed = changed || try_to_repair(i); } } }

	const int sz_cuplaj = count_if(begin(right), end(right), [](const int x){ return x != -1; });
	g << sz_cuplaj << endl;
	for(int i = 0; i < n; ++i){
		if(right[i] != -1){
			g << i+1 << ' ' << right[i]+1 << endl; } }

	return 0; }