Cod sursa(job #2958732)

Utilizator alex_bb8Banilean Alexandru-Ioan alex_bb8 Data 28 decembrie 2022 00:44:05
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.57 kb
#include <bits/stdc++.h>

using namespace std;

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

const int NMAX = 20002;

struct edge{
	int node, flow, capacity, index;
};

int n, m, e;
vector<edge> G[NMAX], adjacent;
vector<bool> visited;
vector<pair<int, int>> parent;

void add_edge(int x, int y){

	G[x].push_back({y, 0, 1, -1});
	G[y].push_back({x, 0, 0, -1});

	G[x][(int) G[x].size() - 1].index = (int) G[y].size() - 1;
	G[y][(int) G[y].size() - 1].index = (int) G[x].size() - 1;

	if(y == n + m + 1)
		adjacent.push_back({x, 0, 1, (int) G[x].size() - 1});
}

void read(){

	f >> n >> m >> e;

	for(int i = 1; i <= e; ++i){
		int x, y;

		f >> x >> y;

		add_edge(x , n + y);
	}

}

bool BFS(int s, int t){

	visited.assign(n + m + 3, false);

	queue<int> Q;

	Q.push(s);

	parent[s] = make_pair(-1, -1);
	visited[s] = true;

	while(!Q.empty()){

		int node = Q.front();

		Q.pop();

		visited[node] = true;

		if(node == t)
			return visited[t];

		for(int j = 0; j < (int) G[node].size(); ++j){

			edge& link = G[node][j];

			if(visited[link.node] == false && link.capacity - link.flow > 0){

				visited[link.node] = true;

				parent[link.node] = make_pair(node, j);

				Q.push(link.node);
			}
		}

	}

	return false;
}

void solve(){

	int max_flow = 0, s = 0, t = n + m + 1;

	parent.assign(n + m + 3, make_pair(-1, -1)); // node, index

	for(int i = 1; i <= n; ++i)
		add_edge(s, i);

	for(int i = 1; i <= m; ++i)
		add_edge(n + i, t);

	while(BFS(s, t)){
		for(auto& x : adjacent){

			if(parent[x.node].first == -1)
				continue;

			int path_flow = INT_MAX;

			parent[t] = {x.node, x.index};

			// find the max flow through the path
			for(int node = t; node != s; node = parent[node].first){
				int aux = parent[node].first, index_node = parent[node].second;

				path_flow = min(path_flow, G[aux][index_node].capacity - G[aux][index_node].flow);
			}

			if(path_flow > 0){

				// update
				for(int node = t; node != s; node = parent[node].first){
					int aux = parent[node].first, index_node = parent[node].second, index_aux = G[aux][index_node].index;

					G[node][index_aux].flow -= path_flow;
					G[aux][index_node].flow += path_flow;
				}

				max_flow += path_flow;
			}
		}
	}

	g << max_flow << '\n';

	for(int node = 1; node <= n; ++node){
		for(auto& link : G[node])
			if(link.flow > 0)
				g << node << ' ' << link.node - n << '\n';
	}

}

int main(){

	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	read();

	solve();

	return 0;
}