【2017/2/25】
【重点:哈夫曼实现 & 优先队列实现小顶堆】
题目:http://ac.jobdu.com/problem.php?pid=1172
http://ac.jobdu.com/problem.php?pid=1107
哈夫曼树的最小权值 = sum(叶节点权值 * 路径长度)
思路:
1、把候选节点放入队列中;
2、每次取出两个最小点,合并后把父节点再投入堆中
3、重复步骤2,直到队列中只有一个结点,即为根节点
实现方式: 中间结点【即非叶节点】的权值 累加求和 即可!【忘了如何证明的话画个草图很容易就看出来了】
#include<cstdio>
#include<queue>
#include<vector>
#include<functional> //不加的话 greater VS2015无法识别
#define maxSize 1005
using namespace std;
int node[maxSize] = { 0 };
//用优先队列实现堆。因为优先队列默认为大顶堆,所以实现小顶堆需要这样声明
priority_queue<int, vector<int>, greater<int> > que;
int main() {
int n;
while (scanf("%d", &n) != EOF) {
while (!que.empty()) que.pop();
for (int i = 0; i < n; i++) {
scanf("%d", &node[i]);
que.push(node[i]);
}
int sum = 0;
while (!que.empty()) {
if (1 == que.size()) { break; } // 只剩根节点
int first = que.top(); //弹出前两个结点
que.pop();
int second = que.top();
que.pop();
int temp = first + second; //合并
sum += temp; //中间结点权值累加
que.push(temp);
}
printf("%d\n", sum);
}
return 0;
}