Cod sursa(job #2464797)

Utilizator mirceatlxhaha haha mirceatlx Data 28 septembrie 2019 22:23:57
Problema Heapuri Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.08 kb
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;

ifstream in("heapuri.in");
ofstream out("heapuri.out");

class Heap
{
public:
    // data structures
    vector < pair <int,int> > _heap; // heap.first --> element ; heap.second --> the i-th element inserted
    vector <int> _pos; // _pos[i] --> the position in the heap of the i-th element
    // constructors
    void Add(int value); // inserts a value into the heap
    void Remove(int value); // removes a node from the heap
    void ExtractMin(); // extracts the root
    void Swim(int Node); // puts the element in the correct position after being inserted in the heap
    void Sink(int Node);
    void Swap(int Node1, int Node2); // operations when swapping nodes
};

void Heap ::Add(int value) {
    _pos.push_back(_heap.size());
    _heap.push_back({value,_pos.size() - 1});
    Swim(_heap.size() - 1);
}

void Heap :: Remove(int value) {
    int position = _pos[value];
    Swap(position,_heap.size() - 1); // changing the element to remove with the last element in the heap
    _heap.pop_back();
    if (position > 1 && _heap[position / 2].first > _heap[position].first)
        // very important case
        Swim(position);
    else
        Sink(position);

}

void Heap :: Swim(int Node) {
    if(Node == 1)
        return;
    int father = Node / 2;
    if(_heap[father].first > _heap[Node].first)
    {
        Swap(father,Node);
        Swim(Node / 2);
    }
}

void Heap :: Swap(int Node1, int Node2){

    swap(_pos[_heap[Node1].second],_pos[_heap[Node2].second]);
    swap(_heap[Node1],_heap[Node2]); // swap the content of the node with index Node1 with the content of the node with index Node2

}

void Heap :: ExtractMin() {
    out << _heap[1].first << "\n"; // root value

}

void Heap :: Sink(int Node) {
    int max_value_index;
    if(2 * Node + 1 > _heap.size() - 1 && 2 * Node > _heap.size() - 1)
        return;
    if(2 * Node + 1 > _heap.size() - 1 && 2 * Node <= _heap.size() - 1 && _heap[2 * Node].first < _heap[Node].first)
    {
        Swap(2 * Node,Node);
        Sink(2 * Node);
        return;
    }
    if(_heap[2 * Node].first < _heap[2 * Node + 1].first)
        max_value_index = 2 * Node;
    else
        max_value_index = 2 * Node + 1;
    if(_heap[max_value_index].first < _heap[Node].first && max_value_index <= _heap.size() - 1)
    {
        Swap(max_value_index,Node);
        Sink(max_value_index);
    }
}

int main()
{
    int debug = 0;
    Heap heap;
    heap._heap.push_back({-1,-1});//operations necessary in order to start the heap from 1
    heap._pos.push_back(-1);// analog up
    int op, cod, x; // number of operations, type of operation, number
    in >> op;
    for(int i = 0 ; i < op ; i++)
    {
        in >> cod;// type of operation
        if(cod == 1)
        {
            in >> x;
            heap.Add(x);

        }
        if(cod == 3)
        {
            heap.ExtractMin(); // getting the value of the root
        }

        if(cod == 2)
        {
            in >> x;
            heap.Remove(x); // removing an element with a specified index from the heap
        }
    }
    return 0;
}