九度题目1172:哈夫曼树
2014-04-15 17:02
369 查看
原题链接:http://ac.jobdu.com/problem.php?pid=1172
题目描述:
哈夫曼树,第一行输入一个数n,表示叶结点的个数。需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题目需要输出所有结点的值与权值的乘积之和。
输入:
输入有多组数据。
每组第一行输入一个数n,接着输入n个叶节点(叶节点权值不超过100,2<=n<=1000)。
输出:
输出权值。
样例输入:
样例输出:
本题用到了优先队列这种数据结构,说实话,原来也没有用过,在优先队列中,元素被赋予优先级。当访问元素时,
具有最高优先级的元素最先删除,我感觉我们只需要知道
4 3 2 1 0
0 1 2 3 4
默认的出对顺序是权值较大的,添加了greater<int>之后,就正好相反了
当然调用priority_queue< int,vector<int>,greater<int> >这个数据结构的时候,需要引用
有了这些预备知识,数据结构的问题就不用担心了,我们就能每次都取出最小的两个数
哈夫曼树的创建的过程就是每次取出当前最小的两个数,然后相加合并,树增高一层,最后权值就是树高*叶子节点的权值,如本题的1 2 2 5 9,37=(1+2)*4+2*3+5*2+9
(图片来源:/article/4853662.html)
我意外的的发现,例如上图求权值,求2 5 7 13的最小带权路径就是(2+5)*3+7*2+13=48
其实也可以这样算,就是所有的非叶子节点之和,即27+14+7=48,测试用例中的37也可以这么算37=19+10+5+3
我的程序就是这么写的,想想也对,非叶子节点不就是所有的叶子节点加起来的吗?理论的证明这个还需要参考
代码如下:
如果文章有什么错误或者有什么建议,欢迎提出,大家共同交流,一起进步
文章转载请注明出处,请尊重知识产权
题目描述:
哈夫曼树,第一行输入一个数n,表示叶结点的个数。需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题目需要输出所有结点的值与权值的乘积之和。
输入:
输入有多组数据。
每组第一行输入一个数n,接着输入n个叶节点(叶节点权值不超过100,2<=n<=1000)。
输出:
输出权值。
样例输入:
5 1 2 2 5 9
样例输出:
37
本题用到了优先队列这种数据结构,说实话,原来也没有用过,在优先队列中,元素被赋予优先级。当访问元素时,
具有最高优先级的元素最先删除,我感觉我们只需要知道
priority_queue<int> q; priority_queue< int,vector<int>,greater<int> > q2; void f(){ int i; for(i=0;i<5;i++){ q.push(i); } for(i=0;i<5;i++){ cout<<q.top()<<" "; q.pop(); } cout<<endl; } void g(){ int i; for(i=0;i<5;i++){ q2.push(i); } for(i=0;i<5;i++){ cout<<q2.top()<<" "; q2.pop(); } cout<<endl; }的结果分别是
4 3 2 1 0
0 1 2 3 4
默认的出对顺序是权值较大的,添加了greater<int>之后,就正好相反了
当然调用priority_queue< int,vector<int>,greater<int> >这个数据结构的时候,需要引用
#include <queue> #include <functional>
有了这些预备知识,数据结构的问题就不用担心了,我们就能每次都取出最小的两个数
哈夫曼树的创建的过程就是每次取出当前最小的两个数,然后相加合并,树增高一层,最后权值就是树高*叶子节点的权值,如本题的1 2 2 5 9,37=(1+2)*4+2*3+5*2+9
(图片来源:/article/4853662.html)
我意外的的发现,例如上图求权值,求2 5 7 13的最小带权路径就是(2+5)*3+7*2+13=48
其实也可以这样算,就是所有的非叶子节点之和,即27+14+7=48,测试用例中的37也可以这么算37=19+10+5+3
我的程序就是这么写的,想想也对,非叶子节点不就是所有的叶子节点加起来的吗?理论的证明这个还需要参考
代码如下:
#include <iostream> #include <functional> #include <queue> using namespace std; int main(int argc, char** argv) { int n,i; priority_queue< int,vector<int>,greater<int> >q; while(cin>>n){ int tmp; for(i=0;i<n;i++){ cin>>tmp; q.push(tmp); } int ans=0; while(q.size()!=1){ int num1=q.top(); q.pop(); int num2=q.top(); q.pop(); int result=num1+num2; ans+=result; q.push(result); } q.pop(); cout<<ans<<endl; } return 0; }
如果文章有什么错误或者有什么建议,欢迎提出,大家共同交流,一起进步
文章转载请注明出处,请尊重知识产权
相关文章推荐
- LeetCode - Sort List
- 编程精华资源大汇总
- 制作一个链表的方法
- MyBatis多参数传递之注解方式示例
- GPS NMEA码格式
- 软考历程(1)——操作系统
- css中定位中的absolute和relative是什么意思
- 6.8 final 关键字 和 6 . 8 . 1 f i n a l 数据
- 数据生成器。。。
- Config程序配置文件操作实践及代码详注
- 算法笔记整理
- Servlet创建、编译、部署、运行
- SHELL脚本分支结构之if
- tesseract-ocr 图像识别所遇到的些问题
- XHTML标签的嵌套规则
- placeholder在不同浏览器下的表现及兼容方法
- javascript中的2个感叹号的用法
- user profile信息同步问题
- Servlet创建、编译、部署、运行
- 网络传输数据封装详解(IP,UDP,TCP)