Pagini recente » Cod sursa (job #882045) | Cod sursa (job #1763057) | Cod sursa (job #2161276) | Cod sursa (job #384425) | Cod sursa (job #2907043)
#include <fstream>
#include <iostream>
#include <queue>
#include <unordered_map>
#include <vector>
using namespace std;
struct Bigraph {
vector<unordered_map<int, int>> cap;
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);
for (auto i = 0; i < nodes_a; i += 1) {
cap[Source()][IndexA(i)] = 1;
cap[IndexA(i)][Source()] = 0;
}
for (auto i = 0; i < nodes_b; i += 1) {
cap[IndexB(i)][Dest()] = 1;
cap[Dest()][IndexB(i)] = 0;
}
}
void Tie(int node_a, int node_b) {
auto a = IndexA(node_a);
auto b = IndexB(node_b);
cap[a][b] = 1;
cap[b][a] = 0;
}
int Flow(int node_a, int node_b) const {
if (!cap[IndexB(node_b)].count(IndexA(node_a))) {
return 0;
}
return cap[IndexB(node_b)].at(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;
}
};
vector<int> FindPre(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& p : graph.cap[node]) {
auto next = p.first;
auto cap = p.second;
if (pre[next] == -1 && cap > 0) {
pre[next] = node;
q.push(next);
}
}
}
return pre;
}
void Flow(Bigraph& graph, const vector<int>& pre, int before_last) {
auto node = graph.Dest();
auto prev = before_last;
auto flow = 1 << 30;
while (prev >= 0) {
flow = min(flow, graph.cap[prev][node]);
node = prev;
prev = pre[prev];
}
node = graph.Dest();
prev = before_last;
while (prev >= 0) {
graph.cap[prev][node] -= flow;
graph.cap[node][prev] += flow;
node = prev;
prev = pre[prev];
}
}
void Flow(Bigraph& graph, const vector<int>& pre) {
for (auto i = 0; i < graph.nodes_b; i += 1) {
auto b = graph.IndexB(i);
if (pre[b] >= 0) {
Flow(graph, pre, b);
}
}
}
vector<pair<int, int>> Solve(Bigraph& graph) {
auto pre = FindPre(graph);
while (pre[graph.Dest()] >= 0) {
Flow(graph, pre);
pre = FindPre(graph);
}
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& p : res) {
fout << p.first + 1 << " " << p.second + 1 << "\n";
}
return 0;
}