Huffman树浅尝

A. POJ-1521 Entropy

#include<cstdio>
#include<string>
#include<queue>
#include<iostream>
#include<algorithm>
using namespace std;

int main(){
	
	string s;
	
	while(getline(cin,s) && s != "END"){
		
		priority_queue<int, vector<int>, greater<int> >ans;
		
		int num_huffman = 0;
		
		sort(s.begin(),s.end());
		
		int cnt = 1;
		for(int i = 1;i < s.length();i++){
			
			if(s[i] != s[i - 1]){
				ans.push(cnt);
				cnt = 1;
			}
			else cnt++;
		} 
		ans.push(cnt);
		
		if(ans.size() == 1)num_huffman = ans.top();
		while(ans.size() > 1){
			int a,b;
			a = ans.top();ans.pop();
			b = ans.top();ans.pop();
			
			ans.push(a + b);
			num_huffman += a + b;//这里要思考为什么这么写 
		}
		//ans.pop();
		
		printf("%d %d %.1lf\n", s.size() * 8,num_huffman, 8.0 * s.size() / num_huffman);
	}
	
	return 0;
} 

B. P6033 合并果子 加强版

#include<bits/stdc++.h>//桶排序+双队列 
#define FAST ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define ms(a,b) memset(a,b,sizeof(a))//memset 是对单个字节的赋值 int数组时只能赋值0,-1 
#define rush() int T;cin>>T;while(T--)
#define ll long long

//10^7的数据会让sort快排TLE 10^5的数据可以桶排 
//再回首才发现这题赫然是huffman树思想.... 2020.5.28 
using namespace std;
const int N = 10e5 + 100;
ll bucket[N];queue<ll>q1,q2;//队列也要开ll 

inline int readint()//快读 
{
	int res = 0;
	char c = 0;
	while(!isdigit(c))
		c = getchar();
	while(isdigit(c))
		res = res * 10 + c - '0', c = getchar();
	return res;	
}

ll sum(){
	ll ans;
	if(q2.empty() || (!q1.empty() && q1.front() < q2.front())){
		ans = q1.front();
		q1.pop();
	}
	else{
		ans = q2.front();
		q2.pop();
	}
	return ans;
}

int main(){
	//ms(bucket,0);
    FAST;
	ll n,term,ans = 0,a,b;
	n = readint();

	for(int i = 1;i <= n;i++){
		term = readint();
		bucket[term]++;
	}
	
	for(int i = 1;i <= 100000;i++)while(bucket[i]--)q1.push(i);
	
	for(int i = 1;i < n;i++){
		a = sum();b = sum();
		ans += a + b;
		q2.push(a + b);
	}
	
	cout<<ans;
	return 0;
} 
//582ms/83.13MB

C. P2168 [NOI2015]荷马史诗

#include<bits/stdc++.h>
#define FAST ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define ms(a,b) memset(a,b,sizeof(a))
#define rush() int T;cin>>T;while(T--)
#define ll long long
//追逐影子的人,自己就是影子 ——荷马
using namespace std;
const int N = 1e5;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1.0);
//广义huffman k叉树 
struct node{
	ll weight,height;
	node(ll W,ll H){
        weight = W,height = H;
    }
}; 

bool operator < (node a,node b) {
		if (a.weight == b.weight) return a.height > b.height;
		return a.weight > b.weight;
}

int main(){
	FAST;
	
	ll n,k,cur,tot = 0,len = 0,cnt = 0;
	//node co;
	priority_queue<node>ans;
	
	cin>>n>>k;
	
	for(int i = 1;i <= n;i++){
		cin>>cur;
		//co.weight = cur;
		//co.height = 1;
		ans.push(node(cur,1));
	} 
	
	if((n - 1) % (k - 1) != 0)cnt = k - 1 - (n - 1) % (k - 1);
	for(int i = 1;i <= cnt;i++)ans.push(node(0,1));
	
	n += cnt;
	while(n > 1){
		ll sum = 0,h = 0;
		
		for(int i = 1;i <= k;i++){
			sum += ans.top().weight;
			h = max(h,ans.top().height);
			ans.pop();
		}
		
		//len++;
		//co.weight = sum;
		//co.height = len;
		ans.push(node(sum,h + 1));
		tot += sum;
		n -= k - 1;
		
	}
	
	cout<<tot<<endl<<ans.top().height - 1;
	return 0;
} 
HUFFMAN树真的有大智慧
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值