哈夫曼树处理这样的一种问题:

给出一棵n个叶子的k叉树,每个叶子有一个权值wi,要求最小化∑wi*di

di表示,第i个叶子节点到根节点的距离。(一般是边数)

处理方法比较固定。

贪心的思路:我们让权值较大的叶子节点 的深度越小越好。

建立一个小根堆。

1.插入n个叶子的权值。

2.每次取出最小的k个,ans+=这些权值和。

3.合并出一个父亲节点,权值就是这k个点的权值和。(通常这一步不用真正实现,只是助于理解)

4.把这个新的父亲节点权值放进小根堆里面。

5.重复2~4操作,直到堆中只有一个节点(就是根节点)

但是这样是有问题的。

发现,我们每取出一次,合并一次,就是相当于把取出来的这些叶子深度+1,

最后一次合并的所有节点,就是根节点的儿子,他们的深度最浅。就是1

而可能出现,最后一次,堆中有2~k-1个节点,不能使最浅的一层放满。

这样肯定是不优的,因为我们可以把较深的一个节点放在根节点的儿子位置上。(因为这一层还没有放满)使得答案更优。

我们这样处理这个问题:

往堆里面不断加入权值为0的及节点。直到满足(tot-1)%(k-1)==0 tot是初始堆中节点个数。

这样,每次都可以恰好取出k个,并且0值的点会先取出来,相当于这里是空位,他们不会影响最后的值。

并且,这样保证了最浅的一层尽可能的放满,就一定是最优解了。

相当于把空位留给了更深的 位置。

例题:

1.合并果子

Description:

n堆果子,合并两堆果子,花费两堆果子的重量之和的力气。问合成一堆最少用多少力气?

Solution:

浅显的解释就是贪心了,因为要合并固定的n-1次,必然每次选择最小的两个合并。

本质上其实是一棵n节点的2叉哈夫曼树。叶子节点的深度米就是这个原始堆被合并的次数。

2.荷马史诗

Description:

荷马史诗

Solution:

我们利用tire树的结构来考虑,为了保证没有前缀包含关系,最后建出的trie必然是有n个叶子节点。

每个叶子节点到根节点的路径长度就是单词长度,并且这个长度要乘上出现的次数wi

恰好就是Huffman的模型!!

一切就很裸了。

但是还要求一个最长的单词最短,,

那么,就在权值相同的节点中,选择之前已经合并过的次数最小的点合并,也就是那些当前深度最浅的点。

这样,把深度“平均”了一下,就是最优的情况了。

另外,新合并出来的点的合并次数,即深度,就是最大的所选点的合并次数。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=+;
int n,k,tot;
ll w[N];
ll ans,mx;
struct node{
ll val,mer;
bool friend operator <(node a,node b){
if(a.val==b.val) return a.mer>b.mer;
return a.val>b.val;
}
};
priority_queue<node>q; int main()
{
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++){
scanf("%lld",&w[i]);
node nn;nn.val=w[i],nn.mer=;
q.push(nn);
}
tot=n;
while((tot-)%(k-)){
node nn;nn.val=;nn.mer=;
q.push(nn);tot++;
}
while(q.size()>){
ll sum=;
ll big=;
for(int i=;i<=k;i++){
node bb=q.top();q.pop();
sum+=bb.val;
big=max(big,bb.mer);
}
mx=max(mx,big+);
ans+=sum;
node kk;kk.val=sum;kk.mer=big+;
q.push(kk);
}
printf("%lld\n%lld",ans,mx);
return ;
}

哈夫曼树Huffman的更多相关文章

  1. Python---哈夫曼树---Huffman Tree

    今天要讲的是天才哈夫曼的哈夫曼编码,这是树形数据结构的一个典型应用. !!!敲黑板!!!哈夫曼树的构建以及编码方式将是我们的学习重点. 老方式,代码+解释,手把手教你Python完成哈夫曼编码的全过程 ...

  2. C++哈夫曼树编码和译码的实现

    一.背景介绍: 给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree).哈夫曼树是带权路径长度最短的树,权值较大的 ...

  3. 数据结构图文解析之:哈夫曼树与哈夫曼编码详解及C++模板实现

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

  4. 赫夫曼\哈夫曼\霍夫曼编码 (Huffman Tree)

    哈夫曼树 给定n个权值作为n的叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree).哈夫曼树是带权路径长度最短的树,权值较大的结点离 ...

  5. NOIP初赛 之 哈夫曼树

    哈夫曼树 种根据我已刷的初赛题中基本每套的倒数第五或第六个不定项选择题就有一个关于哈夫曼树及其各种应用的题,占:0-1.5分:然而我针对这个类型的题也多次不会做,so,今晚好好研究下哈夫曼树: 概念: ...

  6. Android版数据结构与算法(七):赫夫曼树

    版权声明:本文出自汪磊的博客,未经作者允许禁止转载. 近期忙着新版本的开发,此外正在回顾C语言,大部分时间没放在数据结构与算法的整理上,所以更新有点慢了,不过既然写了就肯定尽力将这部分完全整理好分享出 ...

  7. 6-9-哈夫曼树(HuffmanTree)-树和二叉树-第6章-《数据结构》课本源码-严蔚敏吴伟民版

    课本源码部分 第6章  树和二叉树 - 哈夫曼树(HuffmanTree) ——<数据结构>-严蔚敏.吴伟民版        源码使用说明  链接☛☛☛ <数据结构-C语言版> ...

  8. java实现哈弗曼树和哈夫曼树压缩

    本篇博文将介绍什么是哈夫曼树,并且如何在java语言中构建一棵哈夫曼树,怎么利用哈夫曼树实现对文件的压缩和解压.首先,先来了解下什么哈夫曼树. 一.哈夫曼树 哈夫曼树属于二叉树,即树的结点最多拥有2个 ...

  9. 哈夫曼树(C++优先队列的使用)

       给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称为哈夫曼树(Huffman Tree).哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近.    构造 假设有n个权 ...

随机推荐

  1. NB-IOT_BC95_B5常用AT指令集

    .AT+<cmd>=? 测试命令,用于向模块询问支持的设置项目. .AT+<cmd>? 读取命令,用于让模块上报某个命令代表的设置项当前的值. .AT+<cmd>= ...

  2. Bash 笔记

    获取当前工作目录 basepath=$(cd `dirname $0`; pwd) 源文 : https://sexywp.com/bash-how-to-get-the-basepath-of-cu ...

  3. Oracle数据库设置为归档模式的操作方法

    Oracle归档模式非常非常重要!对于有些数据库刚装好后可能是非归档模式,这是很危险的!为了安全起见,一定要谨记:对于Oracle数据库,一定要设置为归档模式,尤其是生产库,只有这样才能实现数据库的有 ...

  4. Mongodb主从复制/ 副本集/分片集群介绍

    前面的文章介绍了Mongodb的安装使用,在 MongoDB 中,有两种数据冗余方式,一种 是 Master-Slave 模式(主从复制),一种是 Replica Sets 模式(副本集). Mong ...

  5. 如何启动Intel VT-X及合理利用搜索

    昨天安装Vmware的时候不幸遇到了Vt-X被禁用的麻烦,上网百度了一下才知道要进入Bois进行设置.说起百度就不得不提到模糊搜索这个概念.这个特性的优点和缺点可谓同等突出,有了模糊搜索大家可以在信息 ...

  6. individual project1 12061183

    1.项目预计用时      之前大二下学期的时候学过面向对象,当时老师叫我们写过一个统计目录下单词的程序,大致的思路是一样的.于是觉得这个程序并不难写.于是就在周末还很轻松地休息着不看程序,知道别的同 ...

  7. Android 學習之旅!(2)

    早幾天因爲學車,弄了幾天時間和精力過去,今天終於考過了(科目二,還是補考的...)嗯..不管這麼多了..今天又開始我的android 學習之旅!! 筆記: platform-tools目錄下的文件: ...

  8. 四则运算APP

    1)   N (Need 需求) 用户基本需求:随机生成四则运算,能自动判定对错,答错时能提示正确答案! 在这个基础上,我的创意: 多用户模式,能记录用户的答题情况(登陆功能) 分级挑战,按照不同的水 ...

  9. [福大软工] Z班 评测作业对应表

    学号 测试组号 011500908 8 031501102 3 031501118 8 031502106 6 031502109 9 031502113 3 031502142 2 03150220 ...

  10. [2017BUAA软工]第零次博客作业

    第一部分:结缘计算机 1. 你为什么选择计算机专业?你认为你的条件如何?和这些博主比呢?(必答) 当年高考前在专业这件事上纠结了好久,因为我对于大学各个专业具体学什么都不甚了解,于是就迟迟没有明确的目 ...