Pagini recente » Cod sursa (job #258973) | Cod sursa (job #239039) | Cod sursa (job #376212) | Cod sursa (job #1133955) | Cod sursa (job #3127835)
#include <fstream>
#include <list>
#include <queue>
using namespace std;
ifstream in("mergeheap.in");
ofstream out("mergeheap.out");
class BinomialHeap
{
private:
struct Node {
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* get_max() {
Node* vmax = new Node;
vmax->value = -1;
Node* root = nullptr;
for (Node* n : heap) {
if (n->value > vmax->value) {
vmax = n;
root = n;
}
}
return root;
}*/
Node* mergetree(Node* t1, Node* t2)
{
/*if (t1 == nullptr || t2 == nullptr) {
return;
}*/
if (t2->value > t1->value) {
Node* aux = t1;
t1 = t2;
t2 = aux;
}
t2->sibling = t1->child;
t1->grad++;
t2->parent = t1;
t1->child = t2;
return t1;
}
/*void adjust() {
if (heap.size() <= 1) {
return;
}
Node* ant = heap.front();
Node* curent = ant->sibling;
Node* urm;
if (curent == nullptr)
urm = nullptr;
else
urm = curent->sibling;
while (curent != nullptr)
{
while (ant->grad == curent->grad && (urm == nullptr || urm->grad > curent->grad))
{
mergeheap(curent, ant);
if (ant == heap.front()) {
heap.pop_front();
heap.push_front(curent);
ant = heap.front();
}
else
ant = ant->sibling;
curent = curent->sibling;
if (curent == nullptr)
urm = nullptr;
else
urm = curent->sibling;
}
ant = curent;
curent = urm;
if (curent == nullptr)
urm = nullptr;
else
urm = curent->sibling;
}
}*/
void adjust() {
heap.sort([](Node* a, Node* b) { return a->grad < b->grad; });
if (heap.size() <= 1) {
return;
}
else {
auto previous = heap.begin();
auto current = previous;
current++;
auto next = current;
next++;
while (current != heap.end()) {
if (next != heap.end()) {
if ((*previous)->grad == (*current)->grad && (*current)->grad != (*next)->grad) {
*previous = mergetree(*previous, *current);
current = heap.erase(current);
next++;
}
else {
previous++;
current++;
next++;
}
}
else {
if ((*previous)->grad == (*current)->grad) {
*previous = mergetree(*previous, *current);
heap.pop_back();
}
current = heap.end();
}
}
}
}
public:
void insert(int val) {
Node* tree = new Node;
tree->value = val;
heap.push_back(tree);
adjust();
}
/*int top() {
return (*get_max()).value;
}*/
void MergeHeap(BinomialHeap& heap2) {
list<Node*> heapFinal;
Node* h1_node;
if (heap.empty())
h1_node = nullptr;
else
h1_node = heap.front();
Node* h2_node;
if (heap2.heap.empty())
h2_node = nullptr;
else
h2_node = 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();
if (heap.empty())
h1_node = nullptr;
else
h1_node = heap.front();
}
else
{
heapFinal.push_back(h2_node);
heap2.heap.pop_front();
if (heap2.heap.empty())
h2_node = nullptr;
else
h2_node = heap2.heap.front();
}
while (h1_node != nullptr) {
heapFinal.push_back(h1_node);
heap.pop_front();
if (heap.empty())
h1_node = nullptr;
else
h1_node = heap.front();
}
while (h2_node != nullptr) {
heapFinal.push_back(h2_node);
heap2.heap.pop_front();
if (heap2.heap.empty())
h2_node = nullptr;
else
h2_node = heap2.heap.front();
}
heap = heapFinal;
adjust();
}
int extract_max() {
if (heap.empty()) {
throw runtime_error("Heap is empty");
}
Node* vmax = new Node;
vmax->value = -1;
Node* max_node = nullptr;
Node* root = nullptr;
for (Node* n : heap) {
if (n->value > vmax->value) {
vmax = n;
max_node = n;
root = 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;
}
/*void print_heap() {
for (Node* n : heap) {
queue<Node*> q;
q.push(n);
while (!q.empty()) {
Node* curent = q.front();
q.pop();
out << curent->value << " ";
if (curent->child != nullptr) {
q.push(curent->child);
Node* sibling = curent->child->sibling;
while (sibling != nullptr) {
q.push(sibling);
sibling = sibling->sibling;
}
}
}
out << endl;
}
}*/
};
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);
}
if (nop == 2)
{
in >> poz1;
out<<heap[poz1].extract_max();
out << endl;
}
if (nop == 3)
{
in >> poz1 >> poz2;
heap[poz1].MergeHeap(heap[poz2]);
}
}
return 0;
}