Cod sursa(job #2885781)

Utilizator tibinyteCozma Tiberiu-Stefan tibinyte Data 6 aprilie 2022 16:18:40
Problema Cuplaj maxim in graf bipartit Scor 90
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.34 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");
struct edge {
	long long a, b, cap, flow;
};
struct Dinic {
	vector<vector<long long>> g;
	vector<long long> level, next;
	vector<edge> edges;
	long long s, t;
	void build(long long n, long long _s , long long _t) {
		s = _s, t = _t;
		g.resize(n + 1), level.resize(n + 1), next.resize(n + 1);
	}
	void add_edge(long long a, long long b, long long cap) {
		long long m = edges.size();
		edges.push_back({ a,b,cap,0 });
		edges.push_back({ b,a,0,0 });
		g[a].push_back(m);
		g[b].push_back(m + 1);
	}
	bool bfs() {
		queue<long long> q;
		q.push(s);
		level[s] = 0;
		while (!q.empty()) {
			long long qui = q.front();
			q.pop();
			for (auto i : g[qui]) {
				edge x = edges[i];
				if (x.cap - x.flow < 1 || level[x.b] != -1) {
					continue;
				}
				level[x.b] = level[x.a] + 1;
				q.push(x.b);
			}
		}
		return level[t] != -1;
	}
	long long dfs(long long node, long long push) {
		if (push == 0) {
			return 0;
		}
		if (node == t) {
			return push;
		}
		for (long long& z = next[node]; z < (long long)g[node].size(); ++z) {
			long long i = g[node][z];
			edge x = edges[i];
			if (x.cap - x.flow < 1 || level[x.b] != level[node] + 1) {
				continue;
			}
			long long flow = dfs(x.b, min(push, x.cap - x.flow));
			if (flow == 0) {
				continue;
			}
			edges[i].flow += flow;
			edges[i ^ 1].flow -= flow;
			return flow;
		}
		return 0;
	}
	long long flow() {
		long long ans = 0;
		while (true) {
			fill(level.begin(), level.end(), -1);
			if (!bfs()) break;
			fill(next.begin(), next.end(), 0);
			while (long long add = dfs(s, 1e18)) {
				ans += add;
			}
		}
		return ans;
	}
};
int main() {
	cin.tie(nullptr)->sync_with_stdio(false);
	int n, m, e;
	fin >> n >> m >> e;
	Dinic G;
	G.build(n + m + 2, 1, n + m + 2);
	for (int i = 1; i <= e; ++i) {
		int a, b;
		fin >> a >> b;
		G.add_edge(a + 1, n + b + 1, 1);
	}
	for (int i = 1; i <= n; ++i) {
		G.add_edge(1, i + 1, 1);
	}
	for (int i = 1; i <= m; ++i) {
		G.add_edge(n + i + 1, n + m + 2, 1);
	}
	fout << G.flow() << '\n';
	for (int i = 0; i < G.edges.size(); ++i) {
		edge x = G.edges[i];
		if (x.a == 1 || x.b == n + m + 2) {
			continue;
		}
		if (x.flow == 1) {
			fout << x.a-1 << ' ' << x.b-n-1 << '\n';
		}
	}
}