- 題目描述:
-
哈夫曼樹,第一行輸入一個數n,表示葉結點的個數。需要用這些葉結點生成哈夫曼樹,根據哈夫曼樹的概念,這些結點有權值,即weight,題目需要輸出所有結點的值與權值的乘積之和。
- 輸入:
-
輸入有多組數據。
每組第一行輸入一個數n,接着輸入n個葉節點(葉節點權值不超過100,2<=n<=1000)。
- 輸出:
-
輸出權值。
- 樣例輸入:
-
5 1 2 2 5 9
- 樣例輸出:
-
37
-
本人的方法是根據哈弗曼編碼做的,第二種方法是使用優先隊列做的,相對簡單。
-
#include<stdio.h> #define MAX_N 1000 #define MAX_BIT 50 #define MAX_WEIGHT 100000 struct HuffNode //節點 { int parent; //父節點 int leftChild; //左孩子 int rightChild; //右孩子 int weight; //權值 }; struct HuffCode //葉節點編碼 { char code[MAX_BIT]; int start; //編碼的起始位置 int weight; }; //生成哈弗曼樹 void huffmanTree(int weight[], int n, HuffNode huffTree[]) { int i,j; //一共有2n-1個節點,前n個葉節點,後n-1個非葉節點 for(i=0;i<2*n-1;i++) //節點初始化 { if(i<n) huffTree[i].weight=weight[i]; else huffTree[i].weight=0; huffTree[i].parent=-1; huffTree[i].leftChild=-1; huffTree[i].rightChild=-1; } //構造n-1個非葉節點 for(i=0;i<n-1;i++) { int m1=MAX_WEIGHT, m2=MAX_WEIGHT, x1=0,x2=0; for(j=0;j<n+i;j++)//找到權值最小的兩個節點 { if(huffTree[j].parent==-1 && huffTree[j].weight<m1) { m2=m1; x2=x1; m1=huffTree[j].weight; x1=j; } else if(huffTree[j].parent==-1 && huffTree[j].weight<m2) { m2=huffTree[j].weight; x2=j; } } huffTree[n+i].weight=m1+m2; huffTree[n+i].leftChild=x1; huffTree[n+i].rightChild=x2; huffTree[x1].parent=n+i; huffTree[x2].parent=n+i; } } void huffmanCode(int n, HuffNode huffTree[],HuffCode huffCodes[]) { int i,j; for(i=0;i<n;i++) //n個葉節點 { int child=i; int parent=huffTree[child].parent; char c; int start=MAX_BIT-1; while(parent!=-1) { if(huffTree[parent].leftChild==child) c='0'; else c='1'; huffCodes[i].code[start]=c; start--; child=parent; parent=huffTree[child].parent; } huffCodes[i].start=start+1; huffCodes[i].weight=huffTree[i].weight; } } int main() { int n; while(scanf("%d",&n)!=EOF) { int i,sum=0; int weight[MAX_N]; HuffNode huffTree[2*MAX_N-1]; HuffCode huffCodes[MAX_N]; for(i=0;i<n;i++) scanf("%d",&weight[i]); huffmanTree(weight,n,huffTree); huffmanCode(n,huffTree,huffCodes); for(i=0;i<n;i++) sum=sum+huffCodes[i].weight*(MAX_BIT-huffCodes[i].start); printf("%d\n",sum); } }
#include<queue> #include<stdio.h> #include<vector> using namespace std; int main() { int n, i ; int temp; while(scanf("%d",&n)!=EOF) { priority_queue <int,vector<int>,greater<int> >q; //建立一個最小堆 int ans=0; for(i=0;i<n;i++) { scanf("%d",&temp); q.push(temp); } while(!q.empty() &&q.size()>1) { int a=q.top(); q.pop(); int b=q.top(); q.pop(); ans+=a+b; q.push(a+b); } printf("%d\n",ans); } return 0; }