Given a list of weights w1, w2, ..., wn, we can construct a binary tree with n leaves, where each leaf is marked with one weight. The is called a weighted binary tree. The weight of the tree is w1l1 + w2l2+ ... wnln, where li is the height of the leaf with weight wi.
For a given list of weights, there are many weighted trees with these weights. However, different weighted tree will have different weights. You are asked to write a program to find the mimimum weight among those weighted trees for a given list of weights.
The first line is the number n of test cases.
The next n lines are the test cases. Each test case is a list of weights that are positive numbers separated by spaces followed by the number 0, which signals the end of the weights.
Each line outputs the minimum weight for the test case.
题目思想为构造哈夫曼树的思想,不过此题不需要生成哈夫曼树,只需要计算出哈夫曼树中的非根结点权值之和即可。
<pre name="code" class="cpp" style="color: rgb(51, 51, 51); font-size: 16px; line-height: 20px;">#include <iostream>
#include <vector>
using namespace std;
//对vector容器进行冒泡排序
void sorts(vector<int> &a) {
for (int i = 1; i < a.size(); ++i) {
for (int j = 0; j < a.size() - i; ++j) {
if (a[j] > a[j+1]) {
int t = a[j];
a[j] = a[j+1];
a[j+1] = t;
}
}
}
}
//构造哈夫曼树,将排序后的数组的前两个元素去除,将前两个元素的和push进数组并排序
void resort(vector<int> &a, int b) {
const unsigned long count = a.size();
for (int i = 0; i < count - 2 ; ++i) {
a[i] = a[i+2];
}
a.pop_back();
a.pop_back();
a.push_back(b);
sorts(a);
}
void minW(vector<int> a) {
sorts(a);
int sum = 0;
while (a.size() != 1) {
int temp = a[0] + a[1];
//计算总权值
sum += temp;
resort(a, temp);
}
cout << sum << endl;
}
int main(int argc, const char * argv[]) {
int cases;
cin >> cases;
for (int i = 0; i < cases; ++i) {
vector<int> weights;
int temp;
while (1) {
cin >> temp;
if (temp != 0) {
weights.push_back(temp);
}
else break;
}
minW(weights);
}
}