关于priority_queue<int,vecto<int>r, greater<int> >, 第一个参数为队列中的数据类型,第二个参数为容器类型,第三个参数为比较方法,常用的有greater,less等,也可以根据实际情况自己去写.当参数为greater<int>时,则可以保证每次插入后队头的数都是最小的数.
Huffman树的构造就不赘述了,使用优先队列每次选择队头的两个数并将其出列,相加后将结果放入队列中,直到队列为空为止.
POJ 1521
计算字符串压缩前后所占的空间,并计算压缩比,赤裸裸的哈夫曼树,先统计字符串中每个字符出现的次数,放入队列中.并不需要编码,只要计算总长度就可以了.
#include <iostream> #include <queue> #include <cstdlib> #include <cstdio> #include <algorithm> using namespace std; int cmp(const void *a,const void *b); int main(){ string line; while(1){ getline(cin,line); if(line=="END")break; priority_queue<int ,vector<int>,greater<int> > qu; //对字符数组排序并将字符个数依次放入优先队列中 sort(line.begin(),line.end()); char c=line[0]; int times=0; for(int i=0;i<line.length();i++){ if(line[i]==c)times++; else{ qu.push(times); c=line[i]; times=1; } } qu.push(times); int oldLen=line.length()*8; int newLen=0; int a,b; if(qu.size()==1)newLen=qu.top(); while(1){ a=qu.top(); qu.pop(); if(qu.empty())break; b=qu.top(); qu.pop(); newLen+=a+b;//这一步很巧,因为编码长度和其在树中的层数相关 qu.push(a+b); } printf("%d %d %.1f\n",oldLen,newLen,oldLen*1.0/newLen); } return 0; }
ZOJ 2399
这一题比上一题更赤裸裸了..只是注意下数据类型是long long和处理只有一个数的时候的情况
#include <iostream> #include <queue> #include <cstdio> using namespace std; int main(){ int n; int nCase; scanf("%d",&nCase); for(int i=0;i<nCase;i++){ scanf("%d",&n); priority_queue<long long,vector<long long>,greater<long long> > qu; while(n-->0){ long long x; scanf("%lld",&x); qu.push(x); } long long a=0,b=0; long long res=0; if(qu.size()==1)res=qu.top(); while(1){ a=qu.top(); qu.pop(); if(qu.empty())break; b=qu.top(); qu.pop(); res+=a+b; qu.push(a+b) ; } printf("%lld\n",res); if(i!=nCase-1)printf("\n"); } return 0; }
POJ 3253
锯木条,将一跟长度为L的木条按指定长度锯成N段,每次锯长度为l的木条花费l cents.分析题意,长度较长应该经过较少的切割次数后得到,类比哈夫曼树出现频度较高的字符编码较短,这题用哈夫曼编码的思路即可解决.
#include <iostream> #include <queue> using namespace std; int main(){ int n; while(cin>>n){ priority_queue<int,vector<int>,greater<int> > qu; while(n-->0){ int x; cin>>x; qu.push(x); } int a=0,b=0; long long res=0; while(1){ a=qu.top(); qu.pop(); if(qu.empty())break; b=qu.top(); qu.pop(); res+=a+b; qu.push(a+b) ; } cout<<res<<endl; } return 0; }