Pagini recente » Cod sursa (job #2236388) | Cod sursa (job #1637730) | Cod sursa (job #430085) | Cod sursa (job #2100847) | Cod sursa (job #3130797)
#include <fstream>
#include <list>
#include <queue>
using namespace std;
ifstream in("mergeheap.in");
ofstream out("mergeheap.out");
class BinomialHeap {
private:
class Node {
public:
int value;
int grad;
Node* child;
Node* sibling;
Node* parent;
Node() : value(0), grad(0), child(nullptr), sibling(nullptr), parent(nullptr) {}
Node(int val) : value(val), grad(0), child(nullptr), sibling(nullptr), parent(nullptr) {}
};
list<Node*> heap;
Node* mergetree(Node* t1, Node* t2) {
if (t2->value > t1->value) {
swap(t1, t2);
}
t2->sibling = t1->child;
t1->grad++;
t2->parent = t1;
t1->child = t2;
return t1;
}
void adjust() {
if (heap.size() <= 1) {
return;
}
heap.sort([](Node* a, Node* b) {
return a->grad < b->grad;
});
auto ant = heap.begin();
auto curr = ant;
auto urm = curr;
urm++;
while (curr != heap.end()) {
if (urm != heap.end() && (*ant)->grad == (*curr)->grad && (*curr)->grad == (*urm)->grad) {
ant = heap.erase(ant);
*ant = mergetree(*ant, *curr);
curr = heap.erase(curr);
urm++;
}
else if ((*ant)->grad == (*curr)->grad) {
*ant = mergetree(*ant, *curr);
curr = heap.erase(curr);
urm++;
}
else {
ant++;
curr++;
urm++;
}
}
}
public:
void insert(int val) {
Node* tree = new Node(val);
heap.push_back(tree);
adjust();
}
void MergeHeap(BinomialHeap& heap2) {
list<Node*> heapFinal;
Node* h1_node = heap.empty() ? nullptr : heap.front();
Node* h2_node = heap2.heap.empty() ? nullptr : heap2.heap.front();
while (h1_node != nullptr && h2_node != nullptr) {
if (h1_node->grad <= h2_node->grad) {
heapFinal.push_back(h1_node);
heap.pop_front();
h1_node = heap.empty() ? nullptr : heap.front();
}
else {
heapFinal.push_back(h2_node);
heap2.heap.pop_front();
h2_node = heap2.heap.empty() ? nullptr : heap2.heap.front();
}
}
while (h1_node != nullptr) {
heapFinal.push_back(h1_node);
heap.pop_front();
h1_node = heap.empty() ? nullptr : heap.front();
}
while (h2_node != nullptr) {
heapFinal.push_back(h2_node);
heap2.heap.pop_front();
h2_node = heap2.heap.empty() ? nullptr : heap2.heap.front();
}
heap = heapFinal;
adjust();
}
int extract_max() {
if (heap.empty()) {
throw runtime_error("Heap is empty");
}
Node* max_node = nullptr;
for (Node* n : heap) {
if (max_node == nullptr || n->value > max_node->value) {
max_node = n;
}
}
int max_value = max_node->value;
heap.remove(max_node);
Node* child = max_node->child;
while (child != nullptr) {
Node* sibling = child->sibling;
child->sibling = nullptr;
heap.push_front(child);
child = sibling;
}
adjust();
return max_value;
}
};
int N, Q, nop, poz1, poz2;
BinomialHeap heap[105];
int main() {
in >> N >> Q;
for (int i = 1; i <= Q; i++) {
in >> nop;
if (nop == 1) {
in >> poz1 >> poz2;
heap[poz1].insert(poz2);
}
else if (nop == 2) {
in >> poz1;
out << heap[poz1].extract_max() << endl;
}
else if (nop == 3) {
in >> poz1 >> poz2;
heap[poz1].MergeHeap(heap[poz2]);
}
}
return 0;
}