Pagini recente » Cod sursa (job #1941156) | Cod sursa (job #1186919) | Cod sursa (job #1362362) | Cod sursa (job #1333928) | Cod sursa (job #2754748)
#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>* mini;
FibonacciHeap<T>()
{
this -> size = 0;
this -> mini = NULL;
}
void Insert(T val)
{
size++;
node<T>* new_node = new node<T>;
new_node->value = val;
new_node->left = new_node;
new_node->right = new_node;
if (mini == NULL)
{
mini = new_node;
return;
}
(mini->left)->right = new_node;
new_node->right = mini;
new_node->left = mini->left;
mini->left = new_node;
if (mini->value < val) // actualizam minimul
mini = new_node;
}
T GetMini()
{
return mini->value;
}
void Cut_Parent_links(node<T>* curr)
{
if (curr == NULL)
return;
node<T> * aux = curr;
do
{
aux->parent = NULL;
aux = aux -> right;
}while (aux != curr);
}
void Cut_Sides(node<T>* curr)
{
if (curr -> right == curr)
return;
node<T>* toLeft = curr ->left;
node<T> * toRight = curr -> right;
toLeft->right = toLeft;
toRight->left = toRight;
}
node<T>* Merge(node<T>* node1, node<T>* node2)
{
if (node1 == NULL) return node2;
if (node2 == NULL) return node1;
if (node1->value < node2->value)
{
node<T>* aux = node2;
node2 = node1;
node1 = aux;
}
node<T>* right1 = node1 -> right;
node<T>* left2 = node2 -> left;
node1->right = node2;
node2->left = node1;
right1->left = left2;
left2->right = right1;
return node1;
}
void Add_child(node<T>* Nodparinte, node<T>* new_child)
{
this->Cut_Sides(new_child);
new_child->left = new_child -> right = new_child;
new_child->parent = Nodparinte;
Nodparinte -> child = Merge(Nodparinte->child, new_child);
Nodparinte ->degree += 1;
}
void _consolidate()
{
int dimension = (int) (log(size)/ log(2)); //every node has degree at most log n - Wikipedia
node<T>* Degrees[dimension + 1];
for (int i = 0; i < dimension + 1; ++i)
Degrees[i] = NULL;
node<T>* itr = mini;
bool flag = 0;
int curr_degree;
do
{
curr_degree = itr -> degree;
while(Degrees[curr_degree] != NULL)
{
node<T> *p = Degrees[curr_degree];
if (p == itr)
{
flag = 1;
break;
}
if (itr -> value < p -> value)
{
node<T>* aux = p;
p = itr;
itr = aux;
}
this->Add_child(itr, p);
Degrees[curr_degree] = NULL;
curr_degree+=1;
}
if (flag) break;
Degrees[itr -> degree] = itr;
itr = itr -> left;
}while (true);
mini = NULL;
node<T>* stop = itr;
do
{
if (mini == NULL || itr -> value < mini -> value)
mini = itr;
itr = itr -> left;
}while (itr != stop);
}
node<T>* _deleteMin()
{
if (mini == NULL)
return NULL;
node<T> *aux = mini;
this->Cut_Parent_links(aux->child);
this ->Merge(aux, aux->child);
this -> Cut_Sides(aux);
size --;
if (aux == aux ->right )
mini = NULL;
else
{
mini = aux -> right;
this -> _consolidate();
}
return aux;
}
void mergeHeaps(FibonacciHeap& otherheap)
{
mini = this->Merge(mini, otherheap.mini);
size += otherheap.size;
otherheap.size = 0;
otherheap.mini = 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].GetMini() << "\n";
multimi[where - 1]._deleteMin();
break;
}
case 3:
{
fin >> where >> who;
multimi[where - 1].mergeHeaps(multimi[who - 1]);
break;
}
}
}
return 0;
}