Processing math: 100%

Huffman-Tree 学习笔记

又是啃课件的一天

定义

构造一棵含n个叶子结点的k叉树, 其中第i个叶子结点权值wi, 要求最小化
widi, di表示i结点的深度。

这样的合法的树被称为(k叉)Huffman

构造方法

增加一些叶子结点为0的结点, 使得它成为满k叉树。将w都丢进小根堆,每次都
取前k小的w,和为s,建立权值为s的节点p,令p成为这k个结点的父亲, 然后把s丢入堆。

证明大概就是要保证权值最小在下面,但是如果不是满k叉树会错,于是就补几个0qwq

感性理解下

应用

这个可以压缩文件的,不过打不过专业软件就对了。

Problem1 NOIP2004 合并果子

想不到吧,二叉Huffman树就可以了,二叉并不用补0。

/*
@Date    : 2019-09-06 21:56:05
@Author  : Adscn (adscn@qq.com)
@Link    : https://www.cnblogs.com/LLCSBlog
*/
#include<bits/stdc++.h>
#include<bits/extc++.h>
using namespace std;
#define IL inline
#define RG register
#define gi getint()
#define gc getchar()
#define File(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
template<typename T>IL bool chkmax(T &x,const T &y){return x<y?x=y,1:0;}
template<typename T>IL bool chkmin(T &x,const T &y){return x>y?x=y,1:0;}
IL int getint()
{
	RG int xi=0;
	RG char ch=gc;
	bool f=0;
	while(!isdigit(ch))ch=='-'?f=1:f,ch=gc;
	while(isdigit(ch))xi=xi*10+ch-48,ch=gc;
	return f?-xi:xi;
}
template<typename T>
IL void pi(T k,char ch=0)
{
	if(k<0)k=-k,putchar('-');
	if(k>=10)pi(k/10,0);
	putchar(k%10+'0');
	if(ch)putchar(ch);
}
__gnu_pbds::priority_queue<int,greater<int> >p;
int main(void)
{
	int n=gi;
	for(int i=1;i<=n;++i)p.push(gi);
	int ans=0;
	while(p.size()>=2){
		int w1=p.top();p.pop();
		int w2=p.top();p.pop();
		int s=w1+w2;
		ans+=s;
		p.push(s);
	}
	pi(ans);
	return 0;
}

Problem2 NOI2015荷马史诗

k叉Huffman树,维护一下深度就可以了。

所以这玩意除了裸题有什么别的用?

/*
@Date    : 2019-09-06 22:03:12
@Author  : Adscn (adscn@qq.com)
@Link    : https://www.cnblogs.com/LLCSBlog
*/
#include<bits/stdc++.h>
#include<bits/extc++.h>
using namespace std;
#define IL inline
#define RG register
#define gi getint()
#define gc getchar()
#define File(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
template<typename T>IL bool chkmax(T &x,const T &y){return x<y?x=y,1:0;}
template<typename T>IL bool chkmin(T &x,const T &y){return x>y?x=y,1:0;}
typedef long long ll;
IL ll getint()
{
	RG ll xi=0;
	RG char ch=gc;
	bool f=0;
	while(!isdigit(ch))ch=='-'?f=1:f,ch=gc;
	while(isdigit(ch))xi=xi*10+ch-48,ch=gc;
	return f?-xi:xi;
}
template<typename T>
IL void pi(T k,char ch=0)
{
	if(k<0)k=-k,putchar('-');
	if(k>=10)pi(k/10,0);
	putchar(k%10+'0');
	if(ch)putchar(ch);
}
typedef pair<ll,int> pll;
__gnu_pbds::priority_queue<pll,greater<pll> >q;
#define fi first
#define se second
#define mp make_pair
int main(void)
{
	int n=gi,k=gi;
	for(int i=1;i<=n;++i)q.push(mp(gi,0));
	while((n-1)%(k-1))q.push(mp(0,0)),++n;
	ll ans=0;
	while(n>1){
		ll sum=0;
		int mh=0;
		for(int i=1;i<=k;++i)sum+=q.top().fi,chkmax(mh,q.top().se),q.pop();
		ans+=sum;
		q.push(mp(sum,mh+1));
		n-=k-1;
	}
	pi(ans,'\n'),pi(q.top().se);
	return 0;
}
posted @   Adscn  阅读(201)  评论(0)    收藏  举报
编辑推荐:
· C#高性能开发之类型系统:从 C# 7.0 到 C# 14 的类型系统演进全景
· 从零实现富文本编辑器#3-基于Delta的线性数据结构模型
· 记一次 .NET某旅行社酒店管理系统 卡死分析
· 长文讲解 MCP 和案例实战
· Hangfire Redis 实现秒级定时任务,使用 CQRS 实现动态执行代码
阅读排行:
· 使用TypeScript开发微信小程序(云开发)-入门篇
· 没几个人需要了解的JDK知识,我却花了3天时间研究
· C#高性能开发之类型系统:从 C# 7.0 到 C# 14 的类型系统演进全景
· 管理100个小程序-很难吗
· 在SqlSugar的开发框架中增加对低代码EAV模型(实体-属性-值)的WebAPI实现支持
点击右上角即可分享
微信分享提示