题目描述
输入描述:
输入有多组数据。 每组第一行输入一个数n,接着输入n个叶节点(叶节点权值不超过100,2<=n<=1000)。
输出描述:
输出权值。
输入
5 1 2 2 5 9
输出
37
分析:
1.此题主要有两个难点,一是如何构造哈夫曼树;二是如何计算叶子节点权值和。
2.在构造哈夫曼树时,学习了如何使用优先队列priority_queue,其是一种可以自行排序的的队列,简单介绍可以参考这篇博客:
https://blog.csdn.net/c20182030/article/details/70757660
在构造优先队列时,priority_queue <int,vector<int>,greater<int> > q;,期中vector<int>表示优先队列是通过vector来实现的。
greater与less对应从小到大排列与从大到小排列。
3.分析哈夫曼树,非叶子节点权值为子节点权值之和,加上该非叶子节点的权值,相当于加上了以其为根节点的所有叶子节点的权值。
当加上所有的非叶子节点的权值时,底层的叶子节点的权值就有了一种“累加”的效果,底层叶子节点所依附的非叶子节点越多,它累加的次数
就越多,也就是从根节点的路径*其权值的效果。
所以:哈夫曼树中,非叶子节点的权值和 即为 该哈夫曼树 叶子节点的带权路径和。
代码:
#include <iostream>
#include <queue>
using namespace std;
int main()
{
int n,i;
int sum=0;
priority_queue<int,vector<int>,greater<int> >q;
cin>>n;
for(i=1;i<=n;i++)
{
int temp;
cin>>temp;
q.push(temp);
}
while(q.size()!=1)
{
int x = q.top();
q.pop();
int y = q.top();
q.pop();
sum += x + y;
q.push(x+y);
}
cout<<sum;
return 0;
}