Cod sursa(job #2959248)

Utilizator vlad082002Ciocoiu Vlad vlad082002 Data 30 decembrie 2022 12:45:05
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.15 kb
#include <bits/stdc++.h>

using namespace std;

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

struct edge {
	int node, f, c, idx;
};

int n, m, e, v[20005];
vector<edge> g[20005], adj;
vector<pair<int, int>> parent;

void addEdge(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].idx = (int) g[y].size() - 1;
	g[y][(int) g[y].size() - 1].idx = (int) g[x].size() - 1;

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

bool bfs(int s, int t) {
    for(int i = 0; i < n + m + 3; i++) v[i] = false;

	queue<int> q;
	q.push(s);

	parent[s] = {-1, -1};
	v[s] = true;

	while(!q.empty()){
		int node = q.front();
		q.pop();

		v[node] = true;
		if(node == t) return true;

		for(int j = 0; j < g[node].size(); j++) {
			edge& muchie = g[node][j];
			if(v[muchie.node] == false && muchie.c - muchie.f > 0) {
				v[muchie.node] = true;
				parent[muchie.node] = {node, j};
				q.push(muchie.node);
			}
		}
	}

	return false;
}

int main() {
	fin >> n >> m >> e;
	for(int i = 1; i <= e; ++i){
		int x, y;
		fin >> x >> y;
		addEdge(x , n + y);
	}

	int maxFlow = 0, s = 0, t = n + m + 1;
	parent.assign(n + m + 3, {-1, -1});

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

	while(bfs(s, t)) {
		for(auto& x : adj) {

			if(parent[x.node].first == -1) continue;
			int pathFlow = 2e9;
			parent[t] = {x.node, x.idx};

			for(int node = t; node != s; node = parent[node].first) {
				int par = parent[node].first;
                int idx = parent[node].second;

				pathFlow = min(pathFlow, g[par][idx].c - g[par][idx].f);
			}

			if(pathFlow > 0) {
				for(int node = t; node != s; node = parent[node].first){
					int par = parent[node].first;
                    int idx = parent[node].second;
                    int idxPar = g[par][idx].idx;

					g[node][idxPar].f -= pathFlow;
					g[par][idx].f += pathFlow;
				}
				maxFlow += pathFlow;
			}
		}
	}

	fout << maxFlow << '\n';

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

}