1. 程式人生 > 實用技巧 >14.模擬堆

14.模擬堆

主要用在圖論的Dijkstra演算法

首先需要知道第k個插入的點是堆裡面的哪個點

還需要知道堆裡面的某個點是第幾個插入的點

第j個插入的點是堆裡面的k

堆裡面的k是第j個插入的點

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 100010;
 4 int h[N], se;
 5 int ph[N], hp[N];
 6 //ph[k]儲存第k個插入的數在堆裡的下標
 7 //hp[k]堆裡面的點是第幾個插入的點 
 8 void heap_swap(int a, int b) {
 9     swap(ph[hp[a]], ph[hp[b]]);
10 swap(hp[a], hp[b]); 11 swap(h[a], h[b]); //交換兩個值 12 } 13 void down(int u) { 14 int t = u; 15 if (u * 2 <= se && h[u * 2] < h[t]) { 16 t = u * 2; 17 } 18 if (u * 2 + 1 <= se && h[u * 2 + 1] < h[t]) { 19 t = u * 2 + 1; 20 } 21 if
(u != t) { 22 heap_swap(u, t); 23 down(t); 24 } 25 } 26 void up(int u) { 27 while (u / 2 && h[u / 2] > h[u]) { 28 heap_swap(u / 2, u); 29 u /= 2; 30 } 31 } 32 int main() { 33 int n; 34 cin >> n; 35 int m = 0; //表示是當前第幾個插入的數 36 while
(n--) { 37 string s; 38 int k, x; 39 cin >> s; 40 if (s == "I") { 41 cin >> x; 42 se++; 43 m++; 44 ph[m] = se; //插入新的數,放在末尾 45 hp[se] = m; 46 h[se] = x; 47 up(se); 48 } else if (s == "PM") { 49 cout << h[1] << endl; 50 } else if (s == "DM") { 51 heap_swap(1, se); 52 se--; 53 down(1); 54 } else if (s == "D") { 55 cin >> k; 56 k = ph[k]; //讓k等於第k個插入的數在堆裡面的位置 57 heap_swap(k, se); 58 se--; 59 down(k); 60 up(k); 61 } else { 62 cin >> k >> x; 63 k = ph[k]; 64 h[k] = x; 65 down(k); 66 up(k); 67 } 68 } 69 return 0; 70 }