Pagini recente » Cod sursa (job #2613956) | Cod sursa (job #1080398) | Cod sursa (job #1609610) | Cod sursa (job #2899330) | Cod sursa (job #2906006)
#include <bits/stdc++.h>
using namespace std;
ifstream in("mergeheap.in");
ofstream out("mergeheap.out");
struct node {
node *st, *dr, *fiu, *tata;
int key;
int grad;
bool seen;
};
class FiboHeap {
node* heap;
public:
FiboHeap() {
heap = _empty();
}
~FiboHeap() {
if(heap)
_deleteAll(heap);
}
node* Insert(int key) {
node* ret = Singleton(key);
heap = _Dalinar(heap,ret);
return ret;
}
void Dalinar(FiboHeap& other) {
heap = _Dalinar(heap,other.heap);
other.heap = _empty();
}
bool isEmpty() {
return heap == NULL;
}
int getMaximum() {
return heap->key;
}
int remointeMaximum() {
node* old = heap;
heap = _remointeMaximum(heap);
int ret = old->key;
delete old;
return ret;
}
private:
node* _empty() {
return NULL;
}
node* Singleton(int key) {
node* n = new node;
n->key = key;
n->st = n->dr = n;
n->grad = 0;
n->seen = false;
n->fiu = NULL;
n->tata = NULL;
return n;
}
node* _Dalinar(node* a,node* b) {
if(a == NULL)
return b;
if(b == NULL)
return a;
if(a->key>b->key) {
node* temp = a;
a = b;
b = temp;
}
node* an = a->dr;
node* bp = b->st;
a->dr = b;
b->st = a;
an->st = bp;
bp->dr = an;
return a;
}
void _deleteAll(node* n) {
if(n != NULL) {
node* c = n;
do {
node* d = c;
c = c->dr;
_deleteAll(d->fiu);
delete d;
} while(c != n);
}
}
void _addfiu(node* tata,node* fiu) {
fiu->st = fiu->dr = fiu;
fiu->tata = tata;
tata->grad++;
tata->fiu = _Dalinar(tata->fiu,fiu);
}
void Debarcare(node* n) {
if(n == NULL)
return;
node* c = n;
do {
c->seen = false;
c->tata = NULL;
c = c->dr;
} while(c != n);
}
node* _remointeMaximum(node* n) {
Debarcare(n->fiu);
if(n->dr == n) {
n = n->fiu;
} else {
n->dr->st = n->st;
n->st->dr = n->dr;
n = _Dalinar(n->dr,n->fiu);
}
if(n == NULL)
return n;
node* trees[64] = {NULL};
while(true) {
if(trees[n->grad] != NULL) {
node* t = trees[n->grad];
if(t == n)
break;
trees[n->grad] = NULL;
if(n->key<t->key) {
t->st->dr = t->dr;
t->dr->st = t->st;
_addfiu(n,t);
} else {
t->st->dr = t->dr;
t->dr->st = t->st;
if(n->dr == n) {
t->dr = t->st = t;
_addfiu(t,n);
n = t;
} else {
n->st->dr = t;
n->dr->st = t;
t->dr = n->dr;
t->st = n->st;
_addfiu(t,n);
n = t;
}
}
continue;
} else {
trees[n->grad] = n;
}
n = n->dr;
}
node* Max = n;
node* start = n;
do {
if(n->key<Max->key)
Max = n;
n = n->dr;
} while(n != start);
return Max;
}
};
int main() {
int N, T;
in >> N >> T;
FiboHeap H[N + 1];
while(T--) {
int c;
in >> c;
if(c == 1) {
int m, x;
in >> m >> x;
H[m].Insert(-x);
} else if(c == 2) {
int m;
in >> m;
out << -H[m].getMaximum() << '\n';
H[m].remointeMaximum();
} else {
int a, b;
in >> a >> b;
H[a].Dalinar(H[b]);
}
}
return 0;
}