1. 程式人生 > >求哈夫曼樹的權值

求哈夫曼樹的權值

題目描述:

哈夫曼樹,第一行輸入一個數n,表示葉結點的個數。需要用這些葉結點生成哈夫曼樹,根據哈夫曼樹的概念,這些結點有權值,即weight,題目需要輸出所有結點的值與權值的乘積之和。

輸入描述:

輸入有多組資料。
每組第一行輸入一個數n,接著輸入n個葉節點(葉節點權值不超過100,2<=n<=1000)。

輸出描述:

輸出權值。

輸入樣例:

5  
1 2 2 5 9

輸出樣例:

37

相關知識:

給定n個權值作為n個葉子結點,構造一棵二叉樹,若該樹的帶權路徑長度達到最小,稱這樣的二叉樹為最優二叉樹,也稱為哈夫曼樹(Huffman Tree)。哈夫曼樹是帶權路徑長度最短的樹,權值較大的結點離根較近。

解題思路:

利用優先佇列來求解,每次從佇列中取出最小值和次小值累加之後再入隊,一直算到結點大小為1,即根結點為止。

AC程式碼:

#include <bits/stdc++.h>
using namespace std;

int main()
{
    map<int,int> m;  //map的key是正整數,value是其在陣列中出現的次數
    int n;
    cin >> n;   //n個正整數
    for (int i = 0; i < n; i++)   //輸入正整數並記錄它們在陣列中出現的次數
    {
        int temp;
        cin >> temp;
        m[temp]++;
    }
    int ans,max=0;   //ans用來存放出現次數最多的正整數,max用來記錄出現最多的次數
    for(auto it:m)   //for-each迴圈遍歷map
    {
        if(it.second > max)    //若某個數出現次數大於max
        {
            max = it.second;   //更新出現最多的次數max
            ans = it.first;    //更新出現最多次的正整數
        }
    }
    cout << ans << endl;
    return 0;
}