洛谷-UVA12676 Inverting Huffman(反转树)

来源:https://www.luogu.com.cn/problem/UVA12676

题目大意:已知huffman编码长度,反过来估计各叶子结点的最小权重和。

这里面的隐含条件就是:
1)求各叶子节点的权重和 = 求huffman树根节点的权重
2)
(重点)上层叶子节点一定至少是下层各节点权重的最大值!(这也解决了如何让叶子节点的权重和最小问题)

最重要的解题思路是:

从上而下推理,假设最深层权重假设全为1(保证得到最小权重),下层节点合并,得到上层新生成的中间节点,而原有的上层的叶子节点等于是下层各节点权重的最大值,再继续合并,直到合并为最终的根节点。

输入:
输入文件包含多个测试用例,每个测试用例如下所述:
第一行包含一个整数 N 2≤N≤50 ),表示文本中出现的不同字符数。
第二行包含 N 个整数 Li 1≤Li≤50 i=1,2, ,N , 表示由 huffman 算法生成的不同字符 的编码长度。
假设至少存在一棵上述算法构建的树,可以生成具有给定长度的编码。
输出:
对每个测试用例,输出一行,表示所有字符总数的最小值。
 
举例:
 
输入:
4
3 1 2 3
 
输出:
5
 

 

洛谷-UVA12676 Inverting Huffman(反转树)_第1张图片

#include 
using namespace std;
vector deep[100]; //已知条件是知道编码长度,则就是知道了该节点的深度,同一深度可能有多次合并。 
int main(){
	int n;
	cin>>n;
	int maxDeep=0; 
	for(int i=0;i>m; //编码长度 等于 节点深度 
		deep[m].push_back(0);//用0占位 
		
		//跟新并记录最大层数 
		if(m>maxDeep){
			maxDeep=m;
		} 
	}
	
	//假设叶子节点的权重(初值为1,因为最深层权重最小为1)
	int temp=1;
	
	//深度为m,则需要m-1次合并,自下而上 
	for(int i=maxDeep;i>0;i--){
		for(int j=0;j

注意:权值可能很大,数组可定义为long long类型

你可能感兴趣的:(洛谷刷算法,反转树,huffman树)