哈夫曼树

题目描述

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

输入

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

输出

输出权值。

样例输入

2
2 8
3
5 11 30

样例输出

10
62

#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;
}
原文地址:https://www.cnblogs.com/sz-wcc/p/11071867.html