Pagini recente » Cod sursa (job #1879458) | Cod sursa (job #1826975) | Cod sursa (job #1546647) | Cod sursa (job #2204913) | Cod sursa (job #2690894)
#include <bits/stdc++.h>
using namespace std;
using T = int;
struct Dinic {
struct Edge { int from, to, nxt; T cap, flow; };
vector<Edge> es;
vector<int> graph, at, dist, q;
Dinic(int n) : graph(n, -1) {}
int AddEdge(int a, int b, T c) {
auto add = [&](int a, int b, T c) {
es.push_back({a, b, graph[a], c, 0});
graph[a] = es.size() - 1;
};
add(a, b, c); add(b, a, 0);
return es.size() - 2;
}
bool bfs(int src, int dest) {
dist.assign(graph.size(), -1); q.clear();
dist[src] = 0; q.push_back(src);
for (int i = 0; i < (int)q.size(); ++i) {
int node = q[i];
for (int ei = graph[node]; ei >= 0; ei = es[ei].nxt) {
const auto &e = es[ei];
if (dist[e.to] == -1 && e.flow < e.cap) {
dist[e.to] = dist[node] + 1;
q.push_back(e.to);
}
}
}
return dist[dest] != -1;
}
T dfs(int node, int dest, T need) {
if (!need) return 0;
if (node == dest) return need;
T ret = 0;
for (int& ei = at[node]; ei != -1; ei = es[ei].nxt) {
const auto &e = es[ei];
if (dist[e.to] != dist[node] + 1) continue;
if (T now = dfs(e.to, dest, min(need, e.cap - e.flow))) {
es[ ei ].flow += now;
es[ei^1].flow -= now;
return now;
ret += now; need -= now;
}
if (!need) break;
}
return ret;
}
T Compute(int src, int dest) {
T ret = 0;
while (bfs(src, dest)) {
at = graph;
while (int now = dfs(src, dest, numeric_limits<T>::max()))
ret += now;
}
return ret;
}
};
int main() {
ifstream cin("cuplaj.in");
ofstream cout("cuplaj.out");
int n, m, k; cin >> n >> m >> k;
Dinic D(n + m + 2);
for (int i = 0; i < n + m; ++i) {
if (i < n) D.AddEdge(n + m, i, 1);
else D.AddEdge(i, n + m + 1, 1);
}
vector<int> es(k);
for (int i = 0; i < k; ++i) {
int a, b; cin >> a >> b; --a; --b;
es[i] = D.AddEdge(a, b + n, 1);
}
cout << D.Compute(n + m, n + m + 1) << endl;
for (int i = 0; i < k; ++i) {
const auto& e = D.es[es[i]];
if (e.flow) cout << e.from + 1 << " " << e.to - n + 1 << '\n';
}
return 0;
}