题目描述
哈夫曼树,第一行输入一个数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(); 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);
cout<<ans<<endl; } return 0; }
|