Pagini recente » Cod sursa (job #234833) | Cod sursa (job #2235551) | Cod sursa (job #1437538) | Cod sursa (job #2721971) | Cod sursa (job #3121855)
// https://www.infoarena.ro/problema/cuplaj
#include <fstream>
#include <vector>
#include <array>
#include <list>
#include <algorithm>
std::ifstream in("cuplaj.in");
std::ofstream out("cuplaj.out");
struct Node {
struct Edge {
Node* from;
Node* to;
int id;
bool matched = false;
Edge(Node* from, Node* to, const int id): from(std::move(from)), to(std::move(to)), id(id) {}
};
Node() = default;
Node(const int id): id(id) {}
int id;
std::vector<Edge> edges = std::vector<Edge>();
Edge* matched = nullptr;
};
struct EdgeRef {
Node::Edge* edge;
EdgeRef* back_ref;
EdgeRef(Node::Edge* edge, EdgeRef* back_ref)
: edge(std::move(edge))
, back_ref(std::move(back_ref)) {}
};
void bfs(Node& start_node, const int max_edges) {
if (start_node.matched) {
return;
}
std::list<EdgeRef> res;
std::vector<bool> visited(max_edges, false);
std::transform(start_node.edges.begin(), start_node.edges.end(), std::inserter(res, res.end()), [&visited](auto& edge) -> EdgeRef {
visited[edge.id] = true;
return {&edge, nullptr};
});
auto it = res.begin();
bool finished = false;
while (it != res.end()) {
if (it->edge->to->matched == nullptr) {
finished = true;
break;
}
for (auto& edge: it->edge->to->edges) {
if (!visited[edge.id] && edge.matched != it->edge->matched) {
res.emplace_back(&edge, &(*it));
}
}
++it;
}
if (finished) {
auto ptr = &(*it);
while (ptr != nullptr) {
ptr->edge->matched = !ptr->edge->matched;
const auto pos = std::find_if(ptr->edge->to->edges.begin(), ptr->edge->to->edges.end(), [&ptr](const auto& edge) {
return edge.to == ptr->edge->from;
});
pos->matched = ptr->edge->matched;
if (ptr->edge->matched) {
ptr->edge->from->matched = ptr->edge;
ptr->edge->to->matched = &(*pos);
} else {
ptr->edge->from->matched = nullptr;
}
ptr = ptr->back_ref;
}
}
}
int main() {
int n, m, e;
in >> n >> m >> e;
std::vector<Node> nodes_a(n), nodes_b(m);
for (int i = 1; i <= n; ++i) {
nodes_a[i-1] = Node(i);
}
for (int i = 1; i <= m; ++i) {
nodes_b[i-1] = Node(i);
}
int a, b;
for (int i = 0; i < e; ++i) {
in >> a >> b;
nodes_a[a-1].edges.emplace_back(&nodes_a[a-1], &nodes_b[b-1], i+i);
nodes_b[b-1].edges.emplace_back(&nodes_b[b-1], &nodes_a[a-1], i+i+1);
}
int count = 0;
for (auto& node: nodes_a) {
bfs(node, e+e);
if (node.matched != nullptr) {
++count;
}
}
out << count << '\n';
for (const auto& node: nodes_a) {
if (node.matched != nullptr) {
out << node.id << ' ' << node.matched->to->id << '\n';
}
}
}