哈夫曼树,第一行输入一个数n,表示叶结点的个数。
需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题目需要输出哈夫曼树的带权路径长度(WPL)。
输入格式:
第一行输入一个数n,第二行输入n个叶结点(叶结点权值不超过1000,2<=n<=1000)。
输出格式:
在一行中输出WPL值。
输入样例:
5 1 2 2 5 9
输出样例:
37

#include<iostream>
#include<stdio.h>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#define MAX 0x3f3f3f3f
using namespace std;
typedef struct
{
int data;
int weight;
int parent;
int lchild;
int rchild;
bool tag;
int deep;
}Huffnode,*HuffmanTree;
HuffmanTree HT;
int n;
void Select(HuffmanTree &HT,int index, int &s1, int &s2)
{
int min1=MAX;
int min2=MAX;
for(int i=1;i<=index;++i)
{
if(HT[i].parent==0&&HT[i].tag)
{
if(HT[i].weight<min1)
{
s1=i;
min1=HT[i].weight;
}
}
}
HT[s1].tag=0;
for(int i=1;i<=index;++i)
{
if(HT[i].parent==0&&HT[i].tag)
{
if(HT[i].weight<min2)
{
s2=i;
min2=HT[i].weight;
}
}
}
HT[s2].tag=0;
}
void CreatHuffmanTree(HuffmanTree &HT,int n)
{
if(n<=1)return;
int m=2*n-1;
HT=new Huffnode[m+1];
for(int i=1;i<=m;++i)
{
HT[i].data=0;
HT[i].weight=0;
HT[i].lchild=0;
HT[i].rchild=0;
HT[i].parent=0;
HT[i].tag=1;
HT[i].deep=0;
}
for(int i=1;i<=n;++i)
{
HT[i].data=i;
scanf("%d",&HT[i].weight);
}
int s1,s2;
for(int i=n+1;i<=m;++i)
{
Select(HT,i-1,s1,s2);
HT[s1].parent=i;
HT[s2].parent=i;
HT[i].lchild=s1;
HT[i].rchild=s2;
HT[i].weight=HT[s1].weight + HT[s2].weight;
HT[i].data=i;
}
}
void Deep(int i)
{
for(int f=1;f<=n;++f)
{
int i=f;
while(i!=2*n-1)
{
HT[f].deep++;
i=HT[i].parent;
}
// cout<<HT[f].weight<<"的深度"<<HT[f].deep<<endl;
}
}
int main()
{
cin>>n;
CreatHuffmanTree(HT,n);
for(int i=1;i<2*n-1;++i)
{
HT[i].tag=1;
}
Deep(1);
int sum=0;
for(int i=1;i<=n;++i)
{
sum+=HT[i].weight*HT[i].deep;
}
cout<<sum;
// for(int i=0;i<2*n-1;++i)
// {
// cout<<HT[i].data<<"|"<<HT[i].weight<<"|"<<HT[i].deep<<"|"<HT[i].rchild<<"|"<<HT[i].lchild<<"|";
// cout<<HT[i].parent<<endl;
// }
}
