题目描述:
Construct an expanded binary tree with nexternal nodes, each external node Ki related to a weight Wi, which minimizes thesum of the external path length of leaf: Min( W1 * L1 + W2 * L2 + W3 * L3 + … + Wn * Ln)
Wi: the weight of each node
Li: the path length betweenthe root and the ith external node. Compute to minimize the sum of the external path length.
输入:The first line is an integer n. n represents the number of external nodes(2<=n<=100). Input n integers in the second line, which represent the weight of each external node.
输出:Output the minimum sum of external path length.
样例输入:
4 1 1 3 5
样例输出:
17
解题思路:
单看第2、3行的公式就知道,这是二叉树叶子结点的最小带权路径问题,是哈夫曼树和哈夫曼编码的变种问题。题目中只需要计算权值,不需要编码,没必要构建哈夫曼树,只需要应用哈夫曼树的一个重要公式:每个叶子的带权路径之和 = 新生成结点的权值和
解题步骤:
1、首先定义一个优先队列,按照升序排序,方便取权值最小的元素;
2、将输入的n个数据作为叶子结点的权值入队;
3、定义一个总和变量,用于存储带权路径和;每次在队中取走最小权值的两个结点,两结点的权值之和作为新生成结点再入队,只要有新生成结点,都要把权值累加到总和变量中;直到队列中的元素少于两个,不能再合并为止。
代码实现:
#include <iostream>
using namespace std;
#include <queue>
priority_queue<int, vector<int>, greater<int> > q;
int main()
{
int n = 0;
cin >> n;
int temp = 0;
while (n--)
{
cin >> temp;
q.push(temp);
}
int father_weight = 0;
int total = 0;
while (q.size() > 1) //元素数量少于2时无法再合并
{
father_weight = 0;
father_weight += q.top();
q.pop();
father_weight += q.top();
q.pop();
q.push(father_weight);
total += father_weight;
}
cout << total << endl;
return 0;
}