哈夫曼树--2018 UESTC Training for Data Structures-H - 中堂系的困难任务

这道题的关键点在于要看出那条式子是哈夫曼树的表达式

哈夫曼树一般可以用来解决一些最佳判定或者编码之类的问题 比如给学生的成绩分类 原理就是把其中元素出现的概率设为树的边权 代价就是边权乘深度的和 构造一棵哈夫曼树主要是dp和贪心两种做法

贪心就是一般教科书讲得从最小元素入手 dp的话就是反过来 因为大的元素肯定应该在树深度比较低的地方 所以把所有元素从大到小排序 一开始假定有一棵大的树 含有一些空的叶节点 每次是两种转移方法要么把第一个没处理的元素插入空的叶节点中 要么把叶节点扩展 然后剩下没处理的权值深度加一 故代价也要加上一次他们的和

具体参见:点击打开链接

这里已知是哈夫曼树的话 直接用贪心的做法就好了 比较好的做法就是用优先队列:

#include <set>
#include <map>
#include <list>
#include <deque>
#include <cmath>
#include <queue>
#include <stack>
#include <bitset>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <iomanip>
#include <cstring>
#include <fstream>
#include <iostream>
#include <algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

typedef long long ll;
priority_queue<ll,vector<ll>,greater<ll> > q;

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        while(!q.empty()) q.pop();
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            ll x;
            scanf("%lld",&x);
            q.push(x);
        }
        ll ans=0;
        while(q.size()>1)
        {
            cout<<q.top()<<endl;
            ll tmp=0;
            tmp+=q.top();
            q.pop();
            tmp+=q.top();
            q.pop();
            ans+=tmp;
            q.push(tmp);
        }
        printf("%lld\n",ans);
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_39302444/article/details/80550009