Pagini recente » Cod sursa (job #195636) | Cod sursa (job #395111) | Cod sursa (job #2763352) | Cod sursa (job #1378831) | Cod sursa (job #2595324)
#pragma once
#include <queue>
#include <iostream>
#include <vector>
#include <stack>
#include <utility>
#include <map>
class Node {
int val;
Node* nextSibling;
Node* firstChild;
static int nrOfNodes;
public:
Node(int val);
void addChild(Node* node);
friend class PairingHeap;
};
class PairingHeap {
Node* root;
static std::map<int, bool> deleted;
public:
PairingHeap();
PairingHeap(int val); //creates a heap with one element(used for insertion)
PairingHeap(Node* root); //initializes a heap with another node(used for deletion)
int getMin();
void show();
int size();
void build(const std::vector<int>& v);
void insert(int val);
void deleteMin();
void deleteVal(int val);
friend PairingHeap& merge(PairingHeap& heap1, PairingHeap& heap2);
};
/*// NODE IMPLEMENTATION //*/
int Node::nrOfNodes = 0;
Node::Node(int val):val(val), nextSibling(nullptr), firstChild(nullptr){
nrOfNodes++;
}
void Node::addChild(Node* node) {
if (this->firstChild == nullptr)
this->firstChild = node;
else {
node->nextSibling = this->firstChild;
this->firstChild = node;
}
}
/*// PAIRING HEAP IMPLEMENTATION //*/
std::map<int, bool> PairingHeap::deleted;
PairingHeap::PairingHeap():root(nullptr){}
PairingHeap::PairingHeap(int val) {
this->root = new Node(val);
}
PairingHeap::PairingHeap(Node* root):root(root){}
void PairingHeap::build(const std::vector<int>& v) {
for (int i = 0; i < v.size(); i++) {
this->insert(v[i]);
}
}
int PairingHeap::getMin() {
return root->val;
}
int PairingHeap::size() {
return Node::nrOfNodes;
}
void PairingHeap::show() {
std::queue<std::pair <Node*, int>> node_queue;
node_queue.push(std::make_pair(this->root, 0));
std::vector<int> parents[21];
while (!node_queue.empty()) {
Node* curr_node = node_queue.front().first;
int parent = node_queue.front().second;
node_queue.pop();
do {
parents[parent].push_back(curr_node->val);
//if I can go down from this node, I add it's child to the queue
if (curr_node->firstChild != nullptr) {
node_queue.push(std::make_pair(curr_node->firstChild, curr_node->val));
}
curr_node = curr_node->nextSibling;
} while (curr_node != nullptr);
}
for(int i = 0; i < 21; i++) {
std::cout << i << ": ";
for (int j = 0; j < parents[i].size(); j++) {
std::cout << parents[i][j] << ' ';
}
std::cout << '\n';
}
}
void PairingHeap::insert(int val) {
PairingHeap tmp(val);
(*this) = merge((*this), tmp);
}
PairingHeap& merge(PairingHeap& heap1, PairingHeap& heap2){
if (heap1.root == nullptr) return heap2;
if (heap2.root == nullptr) return heap1;
if (heap1.getMin() < heap2.getMin()) {
heap1.root->addChild(heap2.root);
return heap1;
}
else {
heap2.root->addChild(heap1.root);
return heap2;
}
}
void PairingHeap::deleteMin() {
Node* childOfRoot = this->root->firstChild;
std::queue<Node*> subHeaps;
while (childOfRoot != nullptr) {
subHeaps.push(childOfRoot);
Node* tmp = childOfRoot->nextSibling;
childOfRoot->nextSibling = nullptr;
childOfRoot = tmp;
}
std::stack<Node*> firstTraversal;
while (subHeaps.size() > 1) {
PairingHeap heap1(subHeaps.front());
subHeaps.pop();
PairingHeap heap2(subHeaps.front());
subHeaps.pop();
firstTraversal.push(merge(heap1, heap2).root);
}
if (subHeaps.size() == 1) {
firstTraversal.push(subHeaps.front());
subHeaps.pop();
}
this->root = nullptr;
while (!firstTraversal.empty()) {
PairingHeap tmpHeap(firstTraversal.top());
(*this) = merge((*this), tmpHeap);
firstTraversal.pop();
}
//if the new minimum has been marked for deletion by lazy deletion, we delete the minimum again
if (this->root != nullptr && deleted[this->root->val])
this->deleteMin();
}
void PairingHeap::deleteVal(int val) {
if (this->root->val == val) {
this->deleteMin();
}
else {
deleted[val] = 1;
}
}
#include <fstream>
std::ifstream in("heapuri.in");
std::ofstream out("heapuri.out");
int main() {
int n;
PairingHeap p;
std::vector<int> ord_val;
in >> n;
for (int i = 0; i < n; i++) {
int op;
in >> op;
if (op == 1) {
int val;
in >> val;
p.insert(val);
ord_val.push_back(val);
}
else if (op == 2) {
int poz;
in >> poz;
int val = ord_val[poz - 1];
p.deleteVal(val);
}
else {
out << p.getMin() << '\n';
}
}
return 0;
}