暑期集训之哈夫曼树

来源:互联网 发布:录像变脸软件是什么 编辑:程序博客网 时间:2024/05/29 07:53

题目描述:

哈夫曼树,第一行输入一个数n,表示叶结点的个数。需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题目需要输出所有结点的值与权值的乘积之和。

输入:

输入有多组数据。
每组第一行输入一个数n,接着输入n个叶节点(叶节点权值不超过100,2<=n<=1000)。

输出:

输出权值。

样例输入:
5  1 2 2 5 9
样例输出:
37
作为第一道接触贪心算法和树的知识的题,看了半天理论,其实哈夫曼树的理论并不是很难理解,它表达的思想就是给你一组权值,每次让这组权值中最小的两组数据相加,并且把相加得到的那个数据来代替原先那两个数据,从而形成新的权值组,然后重复刚才的操作,知道最后一组数据结束,其实这个思想用图的方式表达更为合适,但无奈不方便透漏资料,所以从网上找了点东西来表达(老师嘱咐我们不要把资料放到网上0.0):

哈夫曼树的知识点

好了,相信看了这些东西也就明白是怎么回事了,所以,回到题目,这道题实际上就是找那个最优的情况的权值和,所以用两个数组和一个sort排序就可以实现了,不过这道题也确实有比较高深的做法,涉及到优先序列的用法,个人表示不是很会用,所以先把我的AC代码发上去:

#include<stdio.h>#include<algorithm>#include<string.h>using namespace std;bool cmp(int a,int b){return a>b;}int main(){   int n;while(scanf("%d",&n)!=EOF){    int k=n;int a[1005],b[1005];for(int i=0;i<n;i++)scanf("%d",&a[i]);    for(int j=1;j<k;j++){sort(a,a+n,cmp);a[n-2]=a[n-1]+a[n-2];b[j]=a[n-2];n--; } int sum=0; for(int i=1;i<k;i++) { sum=sum+b[i];  } printf("%d\n",sum);} } 

这个理解起来其实很简单,把问题简单化了,不过如果觉得简单的话可以看下下面这位大神的做法,用到了优先队列的用法,可以学习一下

哈夫曼树 优先队列解决办法

当然还有一种就是建树的思想,也是比较高级的方法,想学习的话也可以看看

哈夫曼树 建树解决办法