#include <iostream> #include <queue> using namespace std; int main() { int n=0,temp=0,sum=0; while(cin >> n && n != 0) { priority_queue<int, vector<int>, greater<int> > MinHeap; for(int i=0;i<n;i++) { cin >> temp; MinHeap.push(temp); } while(MinHeap.size() > 1) { int a = MinHeap.top(); MinHeap.pop(); int b = MinHeap.top(); MinHeap.pop(); sum += (a+b); MinHeap.push(a+b); } cout << sum << endl; sum = 0; } return 0; }
问题分析,主要是类似于哈夫曼编码一样的算法,进行处理,将集合中最小的两个取出来相加,然后再按照这连个数的和再将新的数据放到原始的集合中去,按照小顶堆进行调整。当集合中就剩下一个数据的时候,算法可以退出,然后就可以进行各个叶子节点到达顶端根节点的最短路径。数据结构中的经常使用的一种方法。
现在来熟悉一下STL,使用priority_queue()来建立小顶堆。
priority_queue 对于基本类型的使用方法相对简单。他的模板声明带有三个参数:
priority_queue<Type, Container, Functional>
其中
Type 为数据类型
Container 为保存数据的容器
Functional 为元素比较方式
Container 必须是用数组实现的容器,比如 vector, deque 但不能用 list.
STL里面默认用的是 vector. 比较方式默认用 operator< , 所以如果你把后面俩个参数缺省的话,
优先队列就是大顶堆,队头元素最大。
如果要用到小顶堆,则一般要把模板的三个参数都带进去。
STL里面定义了一个仿函数 greater<>,对于基本类型可以用这个仿函数声明小顶堆
仿函数也叫函数对象(Function Object, or Functor),定义就是任何可以像函数一样被调用的对象。
一个普通的函数是函数对象,一个函数指针当然也是,广义上说任何定义了operator()的类对象都可以看作是函数对象。
仿函数举例:
#include <iostream> #include <algorithm> #include <vector> #include <iterator> using namespace std; int main() { vector<int> a(20); generate(a.begin(),a.end(),rand); for(vector<int>::iterator it = a.begin();it != a.end();it++) cout << (*it)%100 << ' '; cout << endl; return 0; }