Pagini recente » Cod sursa (job #2660080) | Cod sursa (job #2319058) | Cod sursa (job #1460632) | Cod sursa (job #249646) | Cod sursa (job #3263480)
#include <fstream>
#include <vector>
struct Node {
Node(const int index, const bool is_right) {
this->index = index;
this->is_right = is_right;
}
bool IsConnected() {
return connection != nullptr;
}
std::vector<Node*> neighbors;
bool locked = false;
Node* connection = nullptr;
int index;
bool is_right;
};
class Graph {
public:
Graph(const int num_left, const int num_right) {
for (int index = 1; index <= num_left; ++index) {
left_nodes.emplace_back(/*index=*/index, /*is_right=*/false);
}
for (int index = 1; index <= num_right; ++index) {
right_nodes.emplace_back(/*index=*/index, /*is_right=*/true);
}
}
void AddEdge(const int index_left, const int index_right) {
left_nodes[index_left - 1].neighbors.push_back(
&right_nodes[index_right - 1]);
right_nodes[index_right- 1].neighbors.push_back(
&left_nodes[index_left - 1]);
}
int MaximumMatch() {
int solution = 0;
bool was_changed = true;
while (was_changed) {
Unlock();
was_changed = false;
for (Node& node : left_nodes) {
if (node.locked || node.IsConnected()) {
continue;
}
bool success = DFS(node);
solution += success;
was_changed = was_changed || success;
}
}
return solution;
}
std::vector<Node> left_nodes;
std::vector<Node> right_nodes;
private:
void Unlock() {
for (Node& node : left_nodes) {
node.locked = false;
}
for (Node& node : right_nodes) {
node.locked = false;
}
}
bool DFS(Node& node) {
if (node.locked) {
return false;
}
node.locked = true;
if (node.is_right) {
if (!node.IsConnected()) {
return true;
}
return DFS(*node.connection);
}
for (Node* neighbor : node.neighbors) {
if (neighbor == node.connection) {
continue;
}
if (DFS(*neighbor)) {
node.connection = neighbor;
neighbor->connection = &node;
return true;
}
}
return false;
}
};
int main() {
std::ifstream in_file("cuplaj.in");
std::ofstream out_file("cuplaj.out");
int num_left, num_right, num_edges;
in_file >> num_left >> num_right >> num_edges;
Graph graph(num_left, num_right);
for (int edge_index = 0; edge_index < num_edges; ++edge_index) {
int index_left, index_right;
in_file >> index_left >> index_right;
graph.AddEdge(index_left, index_right);
}
out_file << graph.MaximumMatch() << '\n';
for (const Node& node : graph.left_nodes) {
if (node.connection != nullptr) {
out_file << node.index << ' ' << node.connection->index << '\n';
}
}
return 0;
}