在計算WPL值的時候一般是用葉子節點的權值乘上其路徑長度,但是實際上在構建哈夫曼樹的過程中我們其實已經計算過路徑長度了,即
WPL = 哈夫曼樹中所有非葉子結點的權值之和
舉個例子:構造 1 2 2 5 9的哈夫曼樹並計算其WPL值。
上圖即爲構建出來的HuffmanTree,
WPL= (1+2)* 4 + 3 * 2 + 5 * 2 + 9 =37
這個是使用權值乘以路徑長度,但是在計算其中非葉子節點的權值時,3 包含了1個(1+2),5是用3得來的,所以也包含了一個(1+2),同理10和19也是一樣,所以如果直接將所有非葉子節點相加
WPL = 3 + 5 + 10 + 19 = 37。
得到的結果是一樣的。這在實際計算中可以省去再次迭代計算路徑長度的logn的複雜度。
題目描述
哈夫曼樹,第一行輸入一個數n,表示葉結點的個數。需要用這些葉結點生成哈夫曼樹,根據哈夫曼樹的概念,這些結點有權值,即weight,題目需要輸出所有結點的值與權值的乘積之和。
輸入描述:
輸入有多組數據。 每組第一行輸入一個數n,接着輸入n個葉節點(葉節點權值不超過100,2<=n<=1000)。
輸出描述:
輸出權值。
輸入例子:
5
1 2 2 5 9
輸出例子:
37
輸入
5
1 2 2 5 9
輸出
37
#include <iostream>
#include <queue>
#include <stdlib.h>
#include <stdio.h>
#include <map>
#include <string>
#include <cstdlib>
#include <stack>
#include <vector>
#include <math.h>
#include <algorithm>
#include <typeinfo>
#include <cstring>
using namespace std;
const int maxn = 1003;
int data[maxn];
priority_queue<int ,vector<int> ,greater<int>> q;
int main(int argc, char const *argv[])
{
int n;
while(cin>>n){
while(!q.empty()) q.pop();
for(int i=0;i<n;i++){
cin>>data[i];
q.push(data[i]);
}
int ans=0;
while(q.size()>=2){
int a=q.top();q.pop();
int b=q.top();q.pop();
q.push(a+b);
ans+=(a+b);
}
cout<<ans<<endl;
}
return 0;
}