SLT 优先队列 哈弗曼树最小带权路径

与普通的队列不同,普通的队列是先进先出的,而优先队列出队的顺序不是先进先出,而是大(或者小)元素先出队,需要#include <queue>

  1. 成员函数
成员函数 作用
empty() 判断队列是否空
push() 元素如队列
pop() 元素出队,不返回元素
size() 队列里元素的个数
top() 返回队首元素,最大或者最小
  1. 定义&声明
priorty_queue<int> q;//1. 定义一个优先队列,大元素先出队
priority_queue<int, vector<int>, great<int> > q;// 2. 小元素先出队

priority_queue<T, std::vector<T>, cmp> pq;

// 自定义结构体, 

struct node{
    int a;
    int b;

    friend operator < (node x, node y){
        return x.a > y.a;// a小的优先级高
    }
    
};

题目:哈弗曼树的带权路径长度

题目描述

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

输入描述:

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

输出描述:

输出权值。

分析

以下的做法是建立在一个前提之下的,这个前提就是:
一棵哈弗曼树(最优二叉树)的带权最短路径是这棵树的非叶子结点之和,当然目前我也没严格证明出来

#include <iostream>
#include <queue>

using namespace std;

int main(){
    priority_queue< int, vector<int>, greater<int> > q;// 定义一个小值优先的优先队列
    int n, x;
    while(cin >> n){
        int a, b;
        int weight = 0;
        while(!q.empty()){
            q.pop();// 首先清空优先队列
        }
        while(n--){
            cin >> x;
            q.push(x);// enqueue
        }

        while(q.size() > 1){
            a = q.top();
            q.pop();
            b = q.top();
            q.pop();// 获取最小的两个数
            weight += (a + b);// 计算非叶子节点的和
            q.push(a + b);// 把两个最小节点的和加入队列,这和建立哈弗曼树的过程是类似的
        }
        cout << weight << endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zhuobo/p/10296646.html