Pagini recente » Cod sursa (job #212971) | Cod sursa (job #2281092) | Cod sursa (job #442643) | Cod sursa (job #3220614) | Cod sursa (job #3220380)
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
struct Network {
private:
std::vector<std::vector<int>> adj;
std::vector<std::vector<int>> capacity;
std::vector<std::vector<int>> flows;
std::vector<int> parent;
std::vector<bool> group;
int size;
void mark_group(int node) {
group[node] = true;
for (const auto &x: adj[node]) {
if (capacity[node][x] <= 0) continue;
if (group[x]) continue;
mark_group(x);
}
}
int augment(int source, int target) {
parent.assign(size + 1, -1);
parent[source] = -2;
std::queue<std::pair<int, int>> queue;
queue.emplace(source, 1e9);
while (!queue.empty()) {
auto [node, flow] = queue.front();
queue.pop();
for (const auto &x: adj[node]) {
if (parent[x] == -1 && capacity[node][x]) {
parent[x] = node;
int new_flow = std::min(flow, capacity[node][x]);
if (x == target) return new_flow;
queue.emplace(x, new_flow);
}
}
}
return 0;
}
public:
explicit Network(int size) : size(size) {
adj.resize(size + 1);
group.resize(size + 1, false);
capacity.resize(size + 1, std::vector<int>(size + 1, 0));
flows.resize(size + 1, std::vector<int>(size + 1, 0));
}
void add_edge(int x, int y, int cap) {
adj[x].push_back(y);
adj[y].push_back(x);
capacity[x][y] = cap;
}
int max_flow(int source, int target) {
int ans = 0;
int flow = augment(source, target);
while (flow != 0) {
ans += flow;
int node = target;
while (node != source) {
int p = parent[node];
capacity[p][node] -= flow;
flows[p][node] += flow;
capacity[node][p] += flow;
flows[node][p] -= flow;
node = p;
}
flow = augment(source, target);
}
return ans;
}
std::vector<std::vector<int>> get_flow() {
return flows;
}
};
int main() {
freopen("cuplaj.in", "r", stdin);
freopen("cuplaj.out", "w", stdout);
std::ios_base::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
int n, m, k;
std::cin >> n >> m >> k;
Network network(n + m + 1);
for (int i = 1; i <= n; ++i) network.add_edge(0, i, 1);
for (int i = 1; i <= m; ++i) network.add_edge(n + i, n + m + 1, 1);
while (k--) {
int x, y;
std::cin >> x >> y;
network.add_edge(x, n + y, 1);
}
std::cout << network.max_flow(0, n + m + 1) << '\n';
auto flow = network.get_flow();
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
if (flow[i][n + j]) std::cout << i << " " << j << '\n';
}
}
return 0;
}