Cod sursa(job #2470518)

Utilizator Alex18maiAlex Enache Alex18mai Data 9 octombrie 2019 12:46:03
Problema Cuplaj maxim in graf bipartit Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.13 kb
//ALEX ENACHE

#include <vector>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <unordered_map>
#include <time.h>
#include <iomanip>
#include <deque>
#include <math.h>
#include <assert.h>
#include <stack>
#include <bitset>
#include <random>

using namespace std;

//-----------------------------------------------------------------

#include <iostream>
#include <fstream>

//ifstream fin("input"); ofstream fout("output");
ifstream fin("cuplaj.in"); ofstream fout("cuplaj.out");

const int inf = 1e9;
const int MAXN = 20100;

int n, m , e;
int S, D;

vector < int > gr[MAXN];
map < int , int> cap[MAXN];
map < int , int > flow[MAXN];

int dad[MAXN];

queue < int > q;

bool bfs() {
	for (auto& x : dad) {
		x = 0;
	}
	dad[S] = S;
	q.push(S);
	int ok = 0;

	while (!q.empty()) {
		int now = q.front();
		q.pop();
		//cerr << now << '\n';
		if (now == D) {
			ok = 1;
			continue;
		}
		for (auto& x : gr[now]) {
			if (!dad[x] && cap[now][x] - flow[now][x] > 0) {
				dad[x] = now;
				q.push(x);
			}
		}
	}
	return ok;
}

vector < pair < int, int > > edges;

int main() {

	fin >> n >> m >> e;
	S = 20001; D = 20002;

	while (e--) {
		int a, b;
		fin >> a >> b;
		b += 10000;
		cap[a][b] += 1;
		gr[a].push_back(b);
		gr[b].push_back(a);
		edges.push_back({ a, b });
	}

	for (int i = 1; i <= n; i++) {
		gr[S].push_back(i);
		cap[S][i] = 1;
	}

	for (int i = 1; i <= m; i++) {
		gr[i+10000].push_back(D);
		gr[D].push_back(i + 10000);
		cap[i+10000][D] = 1;
	}

	int ans = 0;

	while (bfs()) {
		for (auto& x : gr[D]) {
			if (!dad[x]) {
				continue;
			}
			dad[D] = x;
			int now = D;
			int MIN = inf;
			while (now != S) {
				MIN = min(MIN, cap[dad[now]][now] - flow[dad[now]][now]);
				now = dad[now];
			}
			now = D;
			while (now != S) {
				flow[dad[now]][now] += MIN;
				flow[now][dad[now]] -= MIN;
				now = dad[now];
			}
			ans += MIN;
		}
	}

	fout << ans << '\n';

	for (auto& x : edges) {
		if (flow[x.first][x.second]) {
			fout << x.first << " " << x.second - 10000 << '\n';
		}
	}


	return 0;
}