Cod sursa(job #2961562)

Utilizator R3v1v3RAlexe Paul R3v1v3R Data 6 ianuarie 2023 18:08:00
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.96 kb
/*
	Am aplicat algoritmul Edmonds-Karp avand complexitatea O(n * m * m):
		-> Parcurg graful prin bfs (cautand lanturi intre 1 si n, retinand si arborele bfs)
		-> ma plimb din parinte in parinte pana ajung la 1 pentru a calcula minimul (locul care imi da bottleneck in lant)
*/

#include <bits/stdc++.h>

using namespace std;

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

int n,m,k;
vector< vector<int > > edges;
int cap[20005][20005];
vector<int> arb;
vector<int> vis;
int maxFlow;

bool bfs(){
	fill(arb.begin(), arb.end(),0);
	fill(vis.begin(), vis.end(),0);
	arb[0] = 0;
	vis[0] = 1;
	queue<int> q;
	q.push(0);
	while(!q.empty()){
		int curr = q.front();
		q.pop();

		if(curr == n+m+1)
			return true;
		
		for(int i = 0; i < edges[curr].size(); ++i){
			if(vis[edges[curr][i]] == 0 && cap[curr][edges[curr][i]] > 0){
				arb[edges[curr][i]] = curr;
				vis[edges[curr][i]] = 1;
				q.push(edges[curr][i]);
			}
		}
	}
	return false;
}

int main(){
	fin >> n >> m >> k;
	edges.resize(n+m+2);
	arb.resize(n+m+2);
	vis.resize(n+m+2);

	int a,b,c;

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

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

	for(int i = 0; i < k; ++i){
		fin >> a >> b;
		edges[a].push_back(n+b);
		edges[n+b].push_back(a);
		cap[a][n+b] = 1;
	}
	while(bfs()){
		for(int i = 0; i < edges[n+m+1].size(); ++i){
			if(vis[edges[n+m+1][i]] == 1){
				int fl = INT_MAX;
				arb[n+m+1] = edges[n+m+1][i];
				for(int j = n+m+1; j != 0; j = arb[j]){
					fl = min(fl, cap[arb[j]][j]);
				}
				if(fl != 0){
					for(int j = n+m+1; j != 0; j = arb[j]){
						cap[arb[j]][j] -= fl;
						cap[j][arb[j]] += fl;
					}
					maxFlow += fl;
				}
			}
		}
	}
	fout << maxFlow << '\n';
	for(int i = 1; i <= n; ++i){
		for(int j = 1; j < edges[i].size(); ++j){
			if(cap[i][edges[i][j]] == 0){
				fout << i  << ' ' << edges[i][j] - n  << '\n';
			}
		}
	}
}