Pagini recente » Cod sursa (job #2400725) | Cod sursa (job #1653069) | Cod sursa (job #458834) | Cod sursa (job #2655262) | Cod sursa (job #2907039)
#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<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& p : graph.cap[node]) {
auto next = p.first;
auto cap = p.second;
if (pre[next] == -1 && cap > 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& p : path) {
flow = min(flow, graph.cap[p.first][p.second]);
}
for (const auto& p : path) {
graph.cap[p.first][p.second] -= flow;
graph.cap[p.second][p.first] += flow;
}
}
vector<pair<int, int>> Solve(Bigraph& graph) {
auto path = FindPath(graph);
while (!path.empty()) {
Flow(graph, path);
path = FindPath(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;
}