哈夫曼算法
从跟结点到各叶子节点的路径长度与相应的叶子节点的权值的乘积之和称为二叉树的带权路径长度,带权路长度最小的二叉树称为最优二叉树,也称哈夫曼树.
常见用途有哈夫曼编码问题等.
实现
priority_queue<int, vector<int>, greater<int>> head;
优先队列-greater<int>为小根堆,即默认出队的是当前队列中最小的值.可以理解为从大到小排序.
思路为每次将最小的两个节点结合成一个节点,然后将新的节点重新加入到节点列表中,一次类推重新形成一棵新的二叉树.
蓝桥杯谈判
#include <iostream>
#include <queue>
using namespace std;
int n, t;
int ans = 0;
priority_queue<int, vector<int>, greater<int>> head;
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> t;
head.push(t);
}
for (int i = 1; i <= n - 1; i++)
{
int s = 0;
s += head.top();
head.pop();
s += head.top();
head.pop();
head.push(s);
ans += s;
}
cout << ans;
return 0;
}
POJ 3253 Fence Repair
/*
贪心之哈夫曼编码问题
*/
#include<iostream>
#include<queue>
using namespace std;
int ans = 0;
class myCompare
{
public:
bool operator()(int v1, int v2)const
{
return v1 > v2;
}
};
int n;
priority_queue<int, vector<int>, myCompare> pq;
//从大到小排序,每次将最小的两个出队
int main()
{
cin >> n;
int x;
for (int i = 1; i <= n; i++)
{
cin >> x;
pq.push(x);
}
for (int i = 1; i <= n - 1; i++)
{
int s = 0;
s += pq.top();
pq.pop();
s += pq.top();
pq.pop();
pq.push(s);
ans += s;
}
cout << ans << endl;
return 0;
}
小明的衣服

/*
贪心之哈夫曼编码问题
*/
#include<iostream>
#include<queue>
using namespace std;
long long ans = 0;
class myCompare
{
public:
bool operator()(long long v1, long long v2)const
{
return v1 > v2;
}
};
int n;
priority_queue<long long, vector<long long>, myCompare> pq;
//从大到小排序,每次将最小的两个出队
int main()
{
cin >> n;
int x;
for (int i = 1; i <= n; i++)
{
cin >> x;
pq.push(x);
}
for (int i = 1; i <= n - 1; i++)
{
long long s = 0;
s += pq.top();
pq.pop();
s += pq.top();
pq.pop();
pq.push(s);
ans += s;
}
cout << ans << endl;
return 0;
}