題目來源: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;
}