Pagini recente » Cod sursa (job #36349) | Cod sursa (job #3193326) | Cod sursa (job #2545449) | Cod sursa (job #1072977) | Cod sursa (job #2885781)
#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';
}
}
}