45pts !!玄关求助 !!
查看原帖
45pts !!玄关求助 !!
1108111
XYY62012楼主2025/1/20 15:22

求求求求

/*建哈夫曼树,以求最小值
利用哈夫曼树中权值越高(数据出现频率越高)的节点到根节点
的距离越小(对应哈夫曼编码越短)的性质,
将数据压缩成哈夫曼编码*/
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n,k;
ll n1,n2;
ll sum,maxh,cnt;
struct node{
	ll w;//边权 长度
	ll h;//该节点高度
};
bool operator < (node a,node b){
	if(a.w!=b.w){
		return a.w>b.w;//优先根据其长度排序
	}
	return a.h>b.h;//如果长度相等就按照高度排序
}
priority_queue<node> q;
int main(){
	cin>>n>>k;
	for(int i=1,x;i<=n;i++){
		cin>>x;
		q.push((node){x,1});//强制转换类型,边权和高度
	}	
	if((n-1)%(k-1)){
		cnt=k-1-(n-1)%(k-1);
		//计算出需要填补的节点个数,为了把所有的点都连接构成树
	}
	for(int i=1;i<=cnt;i++){
		q.push((node){0,1});//要补的节点与任意边的长度为0 不影响结果怕
	}
	while(q.size()!=1){
		sum=0;
		maxh=0;
		for(int i=1;i<=k;i++){//操作:合并节点
			sum+=q.top().w;//取队首的最小值合并
			maxh=max(maxh,q.top().h);//找最小值
			q.pop();
		}
		q.push((node){sum,maxh+1});//把合并后的节点再次放入队列
		n1+=sum;//累加长度
		n2=max(maxh,n2);//比较大小,找最短
	}
	cout<<n1<<endl<<n2<<endl;
	return 0;
}
2025/1/20 15:22
加载中...