Pagini recente » Cod sursa (job #2760532) | Cod sursa (job #1480808) | Cod sursa (job #1730088) | Cod sursa (job #2910313) | Cod sursa (job #2906117)
#include <exception>
#include <fstream>
#include <memory>
#include <vector>
template <class T> class Node;
template <class T> using NodePtrT = std::shared_ptr<Node<T>>;
template <class T> class Node {
protected:
using NodePtr = NodePtrT<T>;
T value;
NodePtr next;
NodePtr left;
public:
Node(T value) : value(value), next(nullptr), left(nullptr) {}
T getValue() const { return value; }
NodePtr getLeftChild() const { return left; }
void setLeftChild(const NodePtr &node) { left = node; }
NodePtr getNextSibling() const { return next; }
void setNextSibling(const NodePtr &node) { next = node; }
void addChild(const NodePtr &node) {
if (left != nullptr) {
node->next = left;
}
left = node;
}
};
template <class T, class Compare = std::less<T>> class PairingHeap {
protected:
using NodePtr = NodePtrT<T>;
NodePtr root;
static NodePtr merge(const NodePtr &node1, const NodePtr &node2) {
if (node1 == nullptr) {
return node2;
}
if (node2 == nullptr) {
return node1;
}
if (Compare()(node1->getValue(), node2->getValue())) {
node1->addChild(node2);
return node1;
} else {
node2->addChild(node1);
return node2;
}
return nullptr;
}
static NodePtr twoPassMerge(const NodePtr &node) {
if (node == nullptr || node->getNextSibling() == nullptr) {
return node;
}
auto first = node;
auto second = node->getNextSibling();
auto rest = node->getNextSibling()->getNextSibling();
first->setNextSibling(nullptr);
second->setNextSibling(nullptr);
return merge(merge(first, second), twoPassMerge(rest));
}
public:
bool empty() const { return root == nullptr; }
T min() const {
if (empty()) {
throw std::out_of_range("Heap is empty");
}
return root->getValue();
}
void popMin() { root = twoPassMerge(root->getLeftChild()); }
void insert(T x) { root = merge(root, std::make_shared<Node<T>>(x)); }
void clear() { root = nullptr; }
void absorb(PairingHeap<T, Compare> &rhs) {
root = merge(root, rhs.root);
rhs.root = nullptr;
}
};
int main() {
std::ifstream ifs("mergeheap.in");
int heapCount, opCount;
ifs >> heapCount >> opCount;
std::vector<PairingHeap<int, std::greater<int>>> heaps(heapCount);
std::ofstream ofs("mergeheap.out");
for (int i = 0; i < opCount; ++i) {
int op;
ifs >> op;
if (op == 1) {
int heapIndex, x;
ifs >> heapIndex >> x;
--heapIndex;
heaps[heapIndex].insert(x);
} else if (op == 2) {
int heapIndex;
ifs >> heapIndex;
--heapIndex;
ofs << heaps[heapIndex].min() << '\n';
heaps[heapIndex].popMin();
} else {
int heapIndex1, heapIndex2;
ifs >> heapIndex1 >> heapIndex2;
--heapIndex1;
--heapIndex2;
heaps[heapIndex1].absorb(heaps[heapIndex2]);
heaps[heapIndex2].clear();
}
}
ifs.close();
ofs.close();
return 0;
}