堆的模板及应用 POJ2431
STL库中可以用优先队列实现堆,以下是自己写的堆及其接口
1 //Heap 2 template <typename T> void swap(T &a, T &b){ 3 T t = a; 4 a = b; 5 b = t; 6 } 7 struct Heap{ 8 int data[10005]; 9 int size; 10 Heap(){ 11 for (int i = 0; i < MAXF; ++i) 12 data[i] = 0; 13 size = 0; 14 }; 15 void upAdjust(int cur){ 16 if (cur == 1)return; 17 if (data[cur] > data[cur / 2]){ 18 swap(data[cur], data[cur / 2]); 19 upAdjust(cur / 2); 20 } 21 } 22 void downAdjust(int cur){ 23 int max = cur; 24 if (2 * cur <= size && data[cur] < data[2 * cur])max = 2 * cur; 25 if ((2 * cur + 1) <= size && data[max] < data[2 * cur + 1]) 26 max = 2 * cur + 1; 27 if (max != cur){ 28 swap(data[cur], data[max]); 29 downAdjust(max); 30 } 31 } 32 int pop(){ 33 if (size == 0)return -1; 34 int ret = data[1]; 35 swap(data[1], data[size]); 36 if (--size > 1)downAdjust(1); 37 return ret; 38 } 39 int top(){ 40 return data[1]; 41 } 42 void push(int x){ 43 ++size; 44 data[size] = x; 45 upAdjust(size); 46 } 47 bool empty(){ 48 return size == 0; 49 } 50 /* 51 void build(){ 52 for (int i = (size - 1) >> 2; i >= 0; --i){ 53 downAdjust(i); 54 } 55 } 56 */ 57 };
练习题:
/*Poj 2431 Heap
题意:一辆卡车要行驶L单位距离。最开始时,卡车上有P单位汽油,每向前行驶1单位距离消耗1单位汽油。如果在途中车上的汽油耗尽,则无法到达终点。途中共有N个加油站,加油站提供的油量有限,卡车的油箱无限大。给出每个加油站距离终点的距离和能够提供的油量,问卡车从起点到终点至少要加几次油?如果不能到达终点,输出-1。
分析:因为希望加油次数尽可能少,先假设不需要加油,当行驶到燃料为0了,就会后悔之前路过的加油站,应该找一个油多的站加油。基于贪心的思想,可以用一个优先队列来保存经过的加油站的油量,当需要加油时,取出队列中的最大元素。
*/
1 #include <stdio.h> 2 #include <algorithm> 3 std::pair<int, int> s[MAXF]; 4 int n, l, p; 5 int main(){ 6 // freopen("sample_input.txt", "r", stdin); 7 while (~scanf("%d", &n)){ 8 Heap heap; 9 heap.init(); 10 for (int i = 0; i < n; ++i){ 11 scanf("%d%d", &s[i].first, &s[i].second); 12 } 13 scanf("%d%d", &l, &p); 14 std::sort(s, s + n); 15 heap.push(p); 16 int cnt = -1, index = n - 1; 17 while (l>0 && !heap.empty()){ 18 int tmp = heap.top(); 19 heap.pop(); 20 l -= tmp; 21 ++cnt; 22 while (index >= 0 && l <= s[index].first){ 23 heap.push(s[index].second); 24 --index; 25 } 26 } 27 printf("%d\n", l <= 0 ? cnt : -1); 28 } 29 return 0; 30 }