Pagini recente » Cod sursa (job #1323474) | Cod sursa (job #2947762) | Cod sursa (job #2809820) | Cod sursa (job #3259736) | Cod sursa (job #3294152)
#include <stdio.h>
#include <stdlib.h>
#define MAXN 200005
typedef struct {
int prior; // valoarea elementului
int id; // ID unic (indexul cronologic de inserare)
} ItemType;
typedef struct heap {
long maxHeapSize;
long size;
ItemType *elem;
} PriQueue, *APriQueue;
int idToPos[MAXN]; // id → poziția curentă în heap
int currentId = 0; // ID unic pentru fiecare inserare
// Funcții auxiliare
int getLeftChild(int i) { return 2 * i + 1; }
int getRightChild(int i) { return 2 * i + 2; }
int getParent(int i) { return (i - 1) / 2; }
// Swap și actualizare idToPos
void swap(ItemType *a, ItemType *b) {
ItemType tmp = *a;
*a = *b;
*b = tmp;
}
// Min-heap siftUp
void siftUp(APriQueue h, int idx) {
while (idx > 0 && h->elem[getParent(idx)].prior > h->elem[idx].prior) {
int parent = getParent(idx);
// actualizează maparea
idToPos[h->elem[idx].id] = parent;
idToPos[h->elem[parent].id] = idx;
swap(&h->elem[idx], &h->elem[parent]);
idx = parent;
}
}
// Min-heap siftDown
void siftDown(APriQueue h, int idx) {
int smallest = idx;
while (1) {
int left = getLeftChild(idx);
int right = getRightChild(idx);
if (left < h->size && h->elem[left].prior < h->elem[smallest].prior)
smallest = left;
if (right < h->size && h->elem[right].prior < h->elem[smallest].prior)
smallest = right;
if (smallest != idx) {
idToPos[h->elem[idx].id] = smallest;
idToPos[h->elem[smallest].id] = idx;
swap(&h->elem[idx], &h->elem[smallest]);
idx = smallest;
} else {
break;
}
}
}
PriQueue* makeQueue(int maxHeapSize) {
PriQueue* q = (PriQueue*)malloc(sizeof(PriQueue));
q->maxHeapSize = maxHeapSize;
q->size = 0;
q->elem = (ItemType*)malloc(maxHeapSize * sizeof(ItemType));
return q;
}
void insert(PriQueue *h, ItemType x) {
if (h->size >= h->maxHeapSize) {
h->maxHeapSize *= 2;
h->elem = realloc(h->elem, h->maxHeapSize * sizeof(ItemType));
}
h->elem[h->size] = x;
idToPos[x.id] = h->size;
siftUp(h, h->size);
h->size++;
}
void erase(APriQueue h, int id) {
int pos = idToPos[id];
if (pos >= h->size) return;
// înlocuiește cu ultimul element
h->elem[pos] = h->elem[h->size - 1];
idToPos[h->elem[pos].id] = pos;
h->size--;
// reechilibrare
siftUp(h, pos);
siftDown(h, pos);
}
ItemType getMin(APriQueue h) {
return h->elem[0];
}
void freeQueue(APriQueue h) {
if (h) {
free(h->elem);
free(h);
}
}
int main() {
FILE *fin = fopen("heapuri.in", "r");
FILE *fout = fopen("heapuri.out", "w");
int N;
fscanf(fin, "%d", &N);
PriQueue* heap = makeQueue(4);
for (int i = 0; i < N; i++) {
int op;
fscanf(fin, "%d", &op);
if (op == 1) {
int x;
fscanf(fin, "%d", &x);
ItemType item;
item.prior = x;
item.id = ++currentId;
insert(heap, item);
} else if (op == 2) {
int idToDelete;
fscanf(fin, "%d", &idToDelete);
erase(heap, idToDelete);
} else if (op == 3) {
fprintf(fout, "%d\n", getMin(heap).prior);
}
}
freeQueue(heap);
fclose(fin);
fclose(fout);
return 0;
}