Cod sursa(job #2891788)

Utilizator alex_bb8Banilean Alexandru-Ioan alex_bb8 Data 19 aprilie 2022 21:09:30
Problema Heapuri Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.92 kb
#include <bits/stdc++.h>

using namespace std;

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

//ifstream f("D:/Proiecte/Clion/Projects/hashuri.in");
//ofstream g("D:/Proiecte/Clion/Projects/hashuri.out");

void swap(int *x, int *y) {int aux = *x; *x = *y; *y = aux;}

class MinHeap{

private:
    int *heap, *set_index;
    int capacity, heap_size;

public:

    explicit MinHeap(int capacity) {heap_size = 0; this->capacity = capacity; heap = new int[capacity]; set_index = new int[capacity];};

    ~MinHeap() {delete[] heap; delete[] set_index;};

    int getMin(){return heap[0];}
    int parent(int index) {return index / 2;}
    int left_child(int index) {return 2 * (index);}
    int right_child(int index) {return 2 * (index) + 1;}

    void MinHeapify(int index); 
    int extractMin();
    void decreaseKey(int index, int new_value);
    void deleteKey(int index);
    void insertKey(int value, int set_index);
    void Show(){
        for(int i = 0; i < heap_size; ++i)
            g << heap[i] << ' ';
        g << '\n';
        for(int i = 0; i < heap_size; ++i)
            g << set_index[i] << ' ';
        g << '\n';
    }
};

void MinHeap::MinHeapify(int index) {
    // Heapify a subtree with the root at index

//    g << "MinHeapify" << index << '\n';

    int left  = left_child(index);
    int right = right_child(index);
    int smallest_index = index;

    if(left < heap_size && heap[left] < heap[index])
        smallest_index = left;
    if(right < heap_size && heap[right] < heap[index])
        smallest_index = right;

    if(smallest_index != index){
        swap(&heap[index], &heap[smallest_index]);
        swap(&set_index[index], &set_index[smallest_index]);
        MinHeapify(smallest_index);
    }
}

int MinHeap::extractMin() {
    if(heap_size <= 0)
        return INT_MAX;

    if(heap_size == 1){
        --heap_size;
        return heap[0];
    }

    int root = heap[0];
    heap[0] = heap[heap_size - 1];
    set_index[0] = set_index[heap_size - 1];
    --heap_size;
    MinHeapify(0);

//    Show();
    
    return root;
}

void MinHeap::decreaseKey(int index, int new_value) {
    int found_index;
    for(int i = 0; i < heap_size; ++i)
        if(set_index[i] == index){
            found_index = i;
            break;
        }

    heap[found_index] = new_value;
    set_index[found_index] = new_value;
    while(found_index > 0 && heap[parent(found_index)] > heap[found_index]){
        swap(&heap[found_index], &heap[parent(found_index)]);
        swap(&set_index[found_index], &set_index[parent(found_index)]);
        found_index = parent(found_index);
    }
}

void MinHeap::deleteKey(int index) {
    decreaseKey(index, INT_MIN);
    extractMin();
}

void MinHeap::insertKey(int value, int set_index_value) {
    if(heap_size == capacity){
        cout << "\nCould not insertKey\n";
        return;
    }
    
    // Add the new key at the end
    ++heap_size;
    int index = heap_size - 1;
    heap[index] = value;
    set_index[index] = set_index_value;
    
    // Fix the min heap property if needed
    while(index > 0 && heap[parent(index)] > heap[index]){
        swap(&heap[index], &heap[parent(index)]);
        swap(&set_index[index], &set_index[parent(index)]);
        index = parent(index);
    }
}

int main(){

    int n, set_index = 0;
    f >> n;

    MinHeap H(n);

    for(int i = 1; i <= n; ++i){
        int type, value;

        f >> type;
        switch(type){
            case 1:
                f >> value;
                H.insertKey(value, ++set_index);
                break;
            case 2:
                f >> value;
                H.deleteKey(value);
//                H.Show();
                break;
            case 3:
                g << H.getMin() << '\n';
                break;
        }
    }

    f.close();
    g.close();

    return 0;
}