C. C. Blog

Security Research, Algorithm and Data Structure

哈夫曼树

题目描述

哈夫曼树,第一行输入一个数n,表示叶结点的个数。需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题目需要输出所有结点的值与权值的乘积之和。

输入

输入有多组数据。 每组第一行输入一个数n,接着输入n个叶节点(叶节点权值不超过100,2<=n<=1000)。

输出

输出权值。

样例输入

2 2 8 3 5 11 30

样例输出

10 62

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
#include<stack>
#include<queue>
#define ll long long
using namespace std;
ll n,ans,h[5020];
struct E{
ll k,l,r,t;
friend bool operator < (E x,E y){return x.k>y.k;}
}e[5020];
priority_queue<E>q;
void dfs(ll root){
if(root==0) return;
ll ls=e[root].l,rs=e[root].r;
h[ls]=h[rs]=h[root]+1;
if(ls==0&&rs==0){
ans+=e[root].k*h[root];
}
dfs(ls);
dfs(rs);
}
int main(){
while(cin>>n){
ll cur=n;ans=0;
memset(h,0,sizeof(h));
for(ll i=1;i<=n;i++){
ll x;
cin>>x;
e[i].k=x;
e[i].l=0;
e[i].r=0;
e[i].t=i;
q.push(e[i]);
}
while(q.size()>1){
E xx=q.top();q.pop();
E yy=q.top();q.pop();
//cout<<xx.k<<' '<<yy.k<<endl;
E neww=(E){xx.k+yy.k,xx.t,yy.t,++cur};
e[cur]=neww;
q.push(neww);
}
E root=q.top();q.pop();
h[root.t]=0;
dfs(root.t);
/*for(int i=1;i<=cur;i++){
cout<<e[i].k<<' '<<e[i].l<<' '<<e[i].r<<' '<<e[i].t<<endl;
}*/
cout<<ans<<endl;
}
return 0;
}
  • 本文作者: CCWUCMCTS
  • 本文链接: https://ccwucmcts.github.io/posts/29203/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!