Judge-4080:Huffman编码树

题目来源:http://bailian.openjudge.cn/practice/4080/

描述

构造一个具有n个外部节点的扩充二叉树,每个外部节点Ki有一个Wi对应,作为该外部节点的权。使得这个扩充二叉树的叶节点带权外部路径长度总和最小:

                                     Min( W1 * L1 + W2 * L2 + W3 * L3 + … + Wn * Ln)

Wi:每个节点的权值。

Li:根节点到第i个外部叶子节点的距离。

编程计算最小外部路径长度总和。

输入

第一行输入一个整数n,外部节点的个数。第二行输入n个整数,代表各个外部节点的权值。
2<=N<=100

输出

输出最小外部路径长度总和。

样例输入

4
1 1 3 5

样例输出

17

思路:采用优先队列

反思:单纯计算wpl可以不用构建huffman树,无需知道其分支数,因为始终按照以下规则:取两个最小的节点生成新的节点,最终wpl等于所有新生成节点之和。反之什么时候需要构建huffman树,那是在求叶子节点编码的时候,因为要判断其孩子节点是左右子树。

#include <bits/stdc++.h>
using namespace std;
//优先队列 
//升序(降序为less) 
priority_queue<int,vector<int>,greater<int> > Q;
int main(){
	int n;
	cin>>n;
	for(int i=0;i<n;i++){
		int m;
		cin>>m;
		Q.push(m);
	}
	
	int total=0;//记录新生成的节点之合 
	while(true){
		int sum=0;
		int num1,num2;
		num1=Q.top();
		sum=sum+num1;
		Q.pop();
		num2=Q.top();
		sum=sum+num2;
		Q.pop();
		Q.push(sum);
		total=total+sum;
		
		if(Q.size()==1){
			break;
		}
	}
	
	cout<<total;
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/qq_41877184/article/details/103455174