k叉哈夫曼樹 - NOI2015荷馬史詩

Analysis

k叉哈夫曼樹解析
這道題稍微還需要注意一點的就是最後還要求最長長度最短
這個其實就是在面對兩個權值相同的情況下,優先合併深度較小的點


Code
#include<bits/stdc++.h>
#define re register
#define in read()
using namespace std;
inline char nc(){
	static char buf[100000],*p1=buf,*p2=buf;
	return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
typedef long long ll;
inline ll read(){
	char ch;int f=1;ll res=0;
	while((ch=nc())<'0'||ch>'9') if(ch=='-') f=-1;
	while(ch>='0'&&ch<='9'){
		res=(res<<1)+(res<<3)+(ch^48);
		ch=nc();
	}
	return f==1?res:-res;
}
struct node{
	ll val,dep;
	bool operator <(const node &a)const{
		if(val==a.val) return dep>a.dep;
		return val>a.val;
	}
};
priority_queue<node> q;
const int N=1e5+10;
int n,K;
ll ans=0,ans2=0;
void work(){
	while(n>1){
		ll new_val=0,new_dep=0;
		for(re int i=1;i<=K;++i){
			node tmp=q.top();q.pop();
			new_val+=tmp.val;
			new_dep=max(new_dep,tmp.dep+1);
		}
		q.push((node){new_val,new_dep});
		ans+=new_val;ans2=max(ans2,new_dep);
		n-=(K-1);
	}
	return ;
}
int main(){
//	freopen("data.in","r",stdin);
	ll x;
	n=in;K=in;
	for(re int i=1;i<=n;++i) x=in,q.push((node){x,0});
	int _left=(n-1)%(K-1);
	if(_left){_left=K-1-_left;for(re int i=1;i<=_left;++i)	q.push((node){0,0});}
	work();
	printf("%lld\n%lld",ans,ans2);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章