Cod sursa(job #3126337)

Utilizator mjmilan11Mujdar Milan mjmilan11 Data 6 mai 2023 15:47:15
Problema Heapuri cu reuniune Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.17 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("mergeheap.in");
ofstream fout("mergeheap.out");

const int NMAX = 102;

struct Node{
    int val;
    int rang;
    Node* child;
    Node* sibling;
    Node(){
        val = 0;
        rang = 0;
        child = nullptr;
        sibling = nullptr;
    }
    Node(int _val){
        val = _val;
        rang = 0;
        child = nullptr;
        sibling = nullptr;
    }
};

class Rank_Pairing_Heap{
    Node *root;
    Node *merge_(Node* root1,Node *root2){
        if(root1 == nullptr){
            root1 = root2;
            return root1;
        }
        if(root2 == nullptr) return root1;
        if(root1->val < root2->val) swap(root1,root2);
        /// always merge the smaller one to the bigger
        root2->sibling = root1->child;
        root1->child = root2;
        root1->rang++; /// what makes it Rank-Pairing
        /// keeps the heap balanced
        return root1;
    }
    Node *merge_heap(Node *root1){
        if(root1 == nullptr or root1->sibling == nullptr)
            return root1;
        Node *n1 = root1;
        Node *n2 = root1->sibling;
        Node *urm = n2->sibling;
        n1->sibling = nullptr;
        n2->sibling = nullptr;
        /// creating pairs , merging each other until last merge
        /// repeat the process
        /// in the end our heap is correct;
        return merge_(merge_ (n1,n2),merge_heap(urm));
    }
public:
    Rank_Pairing_Heap(): root(nullptr) {}
    Rank_Pairing_Heap(int _val){
        root = new Node(_val);
    }

    void merge_himself( Rank_Pairing_Heap toMergeHeap ){
        if(root == nullptr){
            root = toMergeHeap.root;
            return;
        }
        if(toMergeHeap.root == nullptr) return;
        if(root->val < toMergeHeap.root->val) swap(root,toMergeHeap.root);
        toMergeHeap.root->sibling = root->child;
        root->child = toMergeHeap.root;
        toMergeHeap.root = nullptr;
    }

    Node* get_root(){
        return root;
    }
    bool empty() const {
        return root == nullptr;
    }
    void push(int nr){
        /// Create new heap , merge himself with the new heap
        merge_himself( Rank_Pairing_Heap(nr) );
    }
    int top(){
        return root->val;
    }
    void pop(){
        /// delete root , reconstruct heap
        Node *last_root = root;
        root = merge_heap(root->child);
        delete last_root;
    }
    void heap_union( Rank_Pairing_Heap &toMergeHeap ){
        /// merge himself with the other heap
        merge_himself( toMergeHeap );
        toMergeHeap.root = nullptr;
        /// other heap has no root now
    }
};

Rank_Pairing_Heap H[NMAX];

int main()
{
    int N,Q,operatie,x,y,m;
    fin >> N >> Q;
    for(int t=1;t<=Q;t++){
        fin >> operatie;
        if(operatie == 1){
            fin >> m >> x;
            H[m].push(x);
        }
        if(operatie == 2){
            fin >> m;
            fout << H[m].top() << '\n';
            H[m].pop();
        }
        if(operatie == 3){
            fin >> x >> y;
            H[x].heap_union(H[y]);
        }
    }
    return 0;
}