Pagini recente » Cod sursa (job #40891) | Cod sursa (job #1210091) | Cod sursa (job #3227528) | Cod sursa (job #2095665) | Cod sursa (job #2907030)
#include <fstream>
#include <iostream>
#include <optional>
#include <queue>
#include <vector>
using namespace std;
struct Bigraph {
vector<vector<int>> cap;
vector<vector<int>> edges;
int nodes_a;
int nodes_b;
Bigraph(int nodes_a, int nodes_b) : nodes_a(nodes_a), nodes_b(nodes_b) {
auto nodes = 2 + nodes_a + nodes_b;
cap.resize(nodes, vector<int>(nodes, 0));
edges.resize(nodes);
for (auto i = 0; i < nodes_a; i += 1) {
cap[Source()][IndexA(i)] = 1;
edges[Source()].push_back(IndexA(i));
edges[IndexA(i)].push_back(Source());
}
for (auto i = 0; i < nodes_b; i += 1) {
cap[IndexB(i)][Dest()] = 1;
edges[IndexB(i)].push_back(Dest());
edges[Dest()].push_back(IndexB(i));
}
}
void Tie(int node_a, int node_b) {
auto a = IndexA(node_a);
auto b = IndexB(node_b);
cap[a][b] = 1;
edges[a].push_back(b);
edges[b].push_back(a);
}
int Flow(int node_a, int node_b) const {
return cap[IndexB(node_b)][IndexA(node_a)];
}
int IndexA(int node_a) const {
return node_a + 2;
}
int IndexB(int node_b) const {
return node_b + nodes_a + 2;
}
int Size() const {
return cap.size();
}
int Source() const {
return 0;
}
int Dest() const {
return 1;
}
const vector<int> operator[](int index) const {
return edges[index];
}
};
optional<vector<pair<int, int>>> FindPath(const Bigraph& graph) {
vector<int> pre(graph.Size(), -1);
pre[graph.Source()] = -2;
queue<int> q;
q.push(graph.Source());
while (!q.empty()) {
auto node = q.front();
q.pop();
for (const auto& next : graph[node]) {
if (pre[next] == -1 && graph.cap[node][next] > 0) {
pre[next] = node;
q.push(next);
}
}
}
if (pre[graph.Dest()] < 0) {
return {};
}
vector<pair<int, int>> path;
for (auto node = graph.Dest(); pre[node] >= 0; node = pre[node]) {
path.push_back({pre[node], node});
}
return path;
}
void Flow(Bigraph& graph, const vector<pair<int, int>>& path) {
auto flow = 1 << 30;
for (const auto& [a, b] : path) {
flow = min(flow, graph.cap[a][b]);
}
for (const auto& [a, b] : path) {
graph.cap[a][b] -= flow;
graph.cap[b][a] += flow;
}
}
vector<pair<int, int>> Solve(Bigraph& graph) {
while (auto path = FindPath(graph)) {
Flow(graph, *path);
}
vector<pair<int, int>> res;
for (auto a = 0; a < graph.nodes_a; a += 1) {
for (auto b = 0; b < graph.nodes_b; b += 1) {
if (graph.Flow(a, b)) {
res.push_back({a, b});
}
}
}
return res;
}
int main() {
ifstream fin("cuplaj.in");
ofstream fout("cuplaj.out");
int nodes_a, nodes_b, edges;
fin >> nodes_a >> nodes_b >> edges;
Bigraph graph(nodes_a, nodes_b);
for (auto i = 0; i < edges; i += 1) {
int a, b;
fin >> a >> b;
graph.Tie(a - 1, b - 1);
}
auto res = Solve(graph);
fout << res.size() << "\n";
for (const auto& [a, b] : res) {
fout << a + 1 << " " << b + 1 << "\n";
}
return 0;
}