题目来源: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;
}