Cod sursa(job #2754724)

Utilizator PopelEmilBogdanPopel Emil-Bogdan PopelEmilBogdan Data 26 mai 2021 13:46:48
Problema Heapuri cu reuniune Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 5.4 kb
#include <bits/stdc++.h>

using namespace std;

template <class T>
class node
{
public:
    T value;
    node * left, *right, *parent, *child;
    int degree;

    node()
    {
        left = NULL;
        right = NULL;
        parent = NULL;
        child = NULL;
        degree = 0;
    }
};

template <class T>
class FibonacciHeap
{
public:
    int size;
    node<T>* pivot;

    FibonacciHeap<T>()
    {
        this -> size = 0;
        this -> pivot = NULL;
    }


    void _insert(T key)
    {
        size++;
        node<T>* inserted = new node<T>;
        inserted->value = key;
        inserted->left = inserted;
        inserted->right = inserted;
        if (pivot == NULL)
        {
            pivot = inserted;
            return;
        }

        (pivot->left)->right = inserted;
        inserted->right = pivot;
        inserted->left = pivot->left;
        pivot->left = inserted;

        if (pivot->value < key) // actualizam minimul
            pivot = inserted;
    }

    T _getMin()
    {
         return pivot->value;
    }

    void _unparent_all(node<T>* current)
    {
        if (current == NULL)
            return;

        node<T> * iterator = current;
        do
        {
            iterator->parent = NULL;
            iterator = iterator -> right;
        }while (iterator != current);
    }

    void _removeCircular(node<T>* current)
    {
        if (current -> right == current)
            return;

        node<T>* Leftcurrent = current ->left;
        node<T> * Rightcurrent = current -> right;

        Leftcurrent->right = Rightcurrent;
        Rightcurrent->left = Leftcurrent;
    }

    node<T>*  _merge(node<T>* x, node<T>* y)
    {
        if (x == NULL) return y;
        if (y == NULL) return x;

        if (x->value < y->value)
        {
            node<T>* aux = y;
            y = x;
            x = aux;
        }

        node<T>* rightX = x -> right;
        node<T>* leftY = y -> left;
        x->right = y;
        y->left = x;

        rightX->left = leftY;
        leftY->right = rightX;
        return x;
    }

    void _make_child(node<T>* parinte, node<T>* newchild)
    {
        this->_removeCircular(newchild);
        newchild->left = newchild -> right = newchild;
        newchild->parent = parinte;
        parinte -> child = _merge(parinte->child, newchild);
        parinte ->degree += 1;
    }


    void _consolidate()
    {
        int Dimension = (int) (log(size)/ log(2));
        node<T>* p_Degree[Dimension + 1];

        for (int i = 0; i < Dimension + 1; ++i)
            p_Degree[i] =  NULL;

        node<T>* iterator = pivot;
        bool break_flag = 0;
        int current_degree;
        do
        {

            current_degree = iterator -> degree;
            while(p_Degree[current_degree] != NULL)
            {
                node<T> *p = p_Degree[current_degree];
                if (p == iterator)
                {
                    break_flag = 1;
                    break;
                }

                if (iterator -> value < p -> value)
                {
                    node<T>* aux = p;
                    p = iterator;
                    iterator = aux;
                }

                this->_make_child(iterator, p);
                p_Degree[current_degree] = NULL;
                current_degree++;
            }

            if (break_flag) break;

            p_Degree[iterator -> degree] = iterator;
            iterator = iterator -> right;
        }while (true);

        pivot = NULL;
        node<T>* stop = iterator;
        do
        {
            if (pivot == NULL || iterator -> value < pivot -> value)
                pivot = iterator;
            iterator = iterator -> right;
        }while (iterator != stop);
    }

    node<T>* _deleteMin()
    {
        if (pivot == NULL)
            return NULL;

        node<T> *aux = pivot;
        this->_unparent_all(aux->child);
        this ->_merge(aux, aux->child);
        this -> _removeCircular(aux);
        size --;

        if (aux == aux ->right )
            pivot = NULL;
        else
        {
            pivot = aux -> right;
            this -> _consolidate();
        }
        return aux;
    }

    void mergeHeaps(FibonacciHeap& fh)
    {
        pivot = this->_merge(pivot, fh.pivot);
        size += fh.size;
        fh.size = 0;
        fh.pivot = NULL;
    }
};


int main()
{

    ifstream fin("mergeheap.in.txt");
    ofstream fout("mergeheap.out.txt");
    int N, K, type, where, who;
    fin >> N >> K;
    vector<FibonacciHeap<int>> multimi;
    for (int i = 0; i < N; ++i)
        multimi.push_back(FibonacciHeap<int>());
    for (; K > 0; K--)
    {
        fin >> type;
        switch(type)
        {
        case 1:
            {
                fin >> where >> who;
                multimi[where - 1]._insert(who);;
                break;
            }
        case 2:
            {
                fin >> where;
                fout << multimi[where - 1]._getMin() << endl;
                multimi[where - 1]._deleteMin();
                break;
            }
        case 3:
            {
                fin >> where >> who;
                multimi[where - 1].mergeHeaps(multimi[who - 1]);
                break;
            }
        }
    }

    return 0;
}