Cod sursa(job #1497834)

Utilizator tamionvTamio Vesa Nakajima tamionv Data 7 octombrie 2015 16:06:53
Problema Cuplaj maxim in graf bipartit Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.14 kb
#include <fstream>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

int flux_maxim(const int surs, const int dest,
	const vector<vector<int> >& adiac, const vector<vector<int> >& cap,
	vector<vector<int> >& flux){
	//presupunem ca flux e umplut cu zerouri
	const int n = adiac.size();
	vector<int> tata(n, -1);
	queue<int> de_viz;
	int rez = 0;
	while(true){
		tata[surs] = surs;
		de_viz.push(surs);
		while(!de_viz.empty()){
			const int cur = de_viz.front();
			de_viz.pop();
			for(const auto next : adiac[cur]){
				if(tata[next] == -1 && cap[cur][next] > flux[cur][next]){
					tata[next] = cur;
					de_viz.push(next); } } }
		if(tata[dest] == -1){
			return rez; }
		for(const auto last : adiac[dest]){
			tata[dest] = last;
			int f_min = 1000000;
			for(int cur = dest; cur != surs && f_min > 0; cur = tata[cur]){
				f_min = min(f_min,
					cap[tata[cur]][cur] - flux[tata[cur]][cur]); }
			if(f_min > 0){
				for(int cur = dest; cur != surs && f_min > 0; cur = tata[cur]){
					flux[tata[cur]][cur] += f_min;
					flux[cur][tata[cur]] -= f_min; }
				rez += f_min; } }
		fill(begin(tata), end(tata), -1); } }

int main(){
	ifstream f("cuplaj.in");
	ofstream g("cuplaj.out");
	int n, m, e;
	f >> n >> m >> e;
	const int st_n = 1, st_m = n+1, n_el = n+m+2;
	vector<vector<int> > adiac(n_el), cap(n_el, vector<int>(n_el, 0)),
		flux(n_el, vector<int>(n_el, 0));
	for(int i = 0; i < n; ++i){
		adiac[0].push_back(st_n+i);
		adiac[st_n+i].push_back(0);
		cap[0][st_n+i] = cap[st_n+i][0] = 1; }

	for(int i = 0; i < m; ++i){
		adiac[n+m+1].push_back(st_m+i);
		adiac[st_m+i].push_back(n+m+1);
		cap[n+m+1][st_m+i] = cap[st_m+i][n+m+1] = 1; }
	for(int i = 0, x, y; i < e; ++i){
		f >> x >> y;
		--x, --y;
		adiac[st_n+x].push_back(st_m+y);
		adiac[st_m+y].push_back(st_n+x);
		cap[st_n+x][st_m+y] = cap[st_m+y][st_n+x] = 1; }
	const int rez = flux_maxim(0, n+m+1, adiac, cap, flux);
	g << rez << '\n';
	for(const auto x : flux){
		for(const auto y : x){
			cout << y << ' '; }
		cout << endl; }

	for(int i = 0; i < n; ++i){
		for(const auto j : adiac[st_n+i]){
			if(flux[st_n+i][j] == 1){
				g << i+1 << ' ' << j-st_m+1 << '\n';
				break; } } }
	return 0; }