Cod sursa(job #3126386)

Utilizator Nicoleta114Caramaliu Nicoleta Nicoleta114 Data 6 mai 2023 16:37:35
Problema Heapuri cu reuniune Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 5.82 kb
#include <iostream>
#include <vector>
#include <list>
#include <fstream>
using namespace std;

ifstream f("mergeheap.in");
ofstream g("mergeheap.out");

struct Nod
{
    int val, nr_copii;
    Nod* parinte;
    Nod* copil;
    Nod* frate;

};

Nod* nod_nou(int valoare)
{
    Nod* nou= new Nod;
    nou->val=valoare;
    nou->parinte=nou->copil=nou->frate=nullptr;
    nou->nr_copii=0;
    return nou;
}

struct HeapBionomial
{
    list<Nod*> arbori;
    ///reunim arborii-arborele cu val mai mica va fi parintele(radacina) arborelui cu val mai mare(va fi adăugat ca un subarbore al rădăcinii)

    Nod* reuniune_arbori(Nod* arbore1, Nod* arbore2)
    {
    if (arbore1->val<arbore2->val) {
        swap(*arbore1, *arbore2);
    }

    arbore2->parinte=arbore1;
    arbore2->frate=arbore1->copil;
    arbore1->copil=arbore2;
    arbore1->nr_copii++;
        return arbore1;
    }

   /* ///creare lista arbori
    void creareArbori(Nod* heap1, Nod* heap2)
    {
        Nod* curent=heap1;
        while(curent!=nullptr)
        {
            arbori.push_front(curent);
            curent=curent->frate;
        }

        curent=heap2;
        while(curent!=nullptr)
        {
            arbori.push_front(curent);
            curent=curent->frate;
        }

        arbori.sort([](Nod* a, Nod* b) {return a->val< b->val;});   ///am sortat arborii crescator dupa cheie(val)


    }*/

    ///reuniune heap-uri binomiale pastrand ordinea crescatoare a cheilor arborilor binomiali

    void modif_lista_arbori()
    {
        ///facem o lista cu toti arborii din cele 2 heap uri in ordine cresc a valorilor
        if (arbori.size()<=1)
        {
            return ;
        }
        else if (arbori.size()==2)
        {
            if (arbori.front()->nr_copii==arbori.back()->nr_copii)
            {
                arbori.front()=reuniune_arbori(arbori.front(), arbori.back());
                arbori.pop_back();
            }
            arbori.sort([](Nod* a, Nod* b) { return a->nr_copii < b->nr_copii; });
            return;
        }

        else {

            list<Nod *>::iterator anterior;
            list<Nod *>::iterator crnt;
            list<Nod *>::iterator urmator;

            anterior = arbori.begin();
            crnt = anterior;
            crnt++;
            urmator = crnt;
            urmator++;

            while (urmator!= arbori.end()) {
                if(crnt== arbori.end()) {
                    if ((*anterior)->nr_copii == ((*crnt)->nr_copii)) {
                        *anterior = reuniune_arbori(*crnt, *anterior);
                        arbori.pop_back();
                        urmator=arbori.end();
                    }
                }
                else if ((*anterior)->nr_copii == ((*crnt)->nr_copii) && ((*crnt)->nr_copii) != ((*urmator)->nr_copii)) {
                    *anterior = reuniune_arbori(*crnt, *anterior);
                    crnt = arbori.erase(crnt);
                    if (urmator != arbori.end()) {
                        urmator++;
                    }
                } else if ((*anterior)->nr_copii == ((*crnt)->nr_copii) &&
                           ((*crnt)->nr_copii) == ((*urmator)->nr_copii)) {
                    anterior++;
                    crnt++;
                    if (urmator != arbori.end()) {
                        urmator++;
                    }
                } else if ((*anterior)->nr_copii < ((*crnt)->nr_copii)) {
                    anterior++;
                    crnt++;
                    if (urmator != arbori.end()) {
                        urmator++;
                    }
                }
            }
        }

            arbori.sort([](Nod* a, Nod* b) { return a->nr_copii < b->nr_copii; });

    }

    ///reunim heapuri

    void reuniune_heap(HeapBionomial& heap2)
    {
        list<Nod*> HeapFinal;
        list<Nod*> :: iterator a1, a2;
        a1=arbori.begin();
        a2= heap2.arbori.begin();

        while(a1!=arbori.end() && a2!=heap2.arbori.end())
        {
            if((*a2)->nr_copii>=(*a1)->nr_copii)
            {
                HeapFinal.push_front(*a1);
                a1++;
            }
            else
            {
                HeapFinal.push_front(*a2);
                a2++;
            }
            while (a1!=arbori.end())
            {
                HeapFinal.push_front(*a1);
                a1++;
            }

            while (a2!=heap2.arbori.end())
            {
                HeapFinal.push_front(*a2);
                a2++;
            }
        }

        heap2.arbori.clear();
        arbori=HeapFinal;
        modif_lista_arbori();

    }

    /// inseram un nod nou in heap
    void inserare_val(int valoare)
    {
        Nod* nou=nod_nou(valoare);
        arbori.push_back(nou);
        modif_lista_arbori();
    }

    ///gasim radacina cu valoarea maxima si o eliminam

    void eliminare()
    {
        if (arbori.empty()) {
            return ;
        }

        auto it = arbori.begin();
        Nod* max = *it;
        while (it != arbori.end()) {
            if ((*it)->val > max->val) {
                max= *it;
            }
            it++;
        }

        arbori.remove(max);
        list<Nod*> subarbori;
        Nod* sa=max->copil;
        g<<(*max).val<<endl;
        while (sa!=NULL)
        {
            subarbori.push_front(sa);
            sa=sa->frate;
        }
        arbori.merge(subarbori);
        modif_lista_arbori();
    }

};

int main()
{
    int mult,op;
    f>>mult >>op;
    HeapBionomial Heap[101];
    int nrOp, it, valoare, i1, i2;
    for (int i = 1; i <=op; i++) {
        f >> nrOp;
        if (nrOp == 1) {
            f >> it;
            f >> valoare;
            Heap[it].inserare_val(valoare);

        } else if (nrOp == 2) {
            f >> it;
            Heap[it].eliminare();
        } else if (nrOp == 3) {
            f >> i1 >> i2;
            Heap[i1].reuniune_heap(Heap[i2]);
        }
    }
    return 0;
}