荷马史诗

荷马史诗

题解

一道Huffman树的模板题。尽管笔者考试时未做出来(因为不会Huffman)

其实到我们明白题意后就可以知道此题就是在一棵k叉树上旋n个点,使没有一个点的祖先被选。

研究到这里,很明显的一道Huffman的模板,至于Huffman具体怎么实现就不再说明了。

源码

//#pragma GCC optimize(3)
//#pragma GCC optimize(2)
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#define MAXN 100005
using namespace std;
typedef long long LL;
#define gc() getchar()
template<typename _T>
inline void read(_T &x){
	_T f=1;x=0;char s=gc();
	while(s>'9'||s<'0'){if(s=='-')f=-1;s=gc();}
	while(s>='0'&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=gc();}
	x*=f;
} 
struct ming{
	LL val,dep;
	ming(){val=dep=0;}
	ming(LL V,LL D){
		val=V;dep=D;
	}
	bool friend operator < (const ming &x,const ming &y){
		if(x.val==y.val)return x.dep>y.dep;
		return x.val>y.val;
	}
};
int n,k;
LL w[MAXN],ans;
priority_queue<ming> q;
signed main() {
	read(n);read(k);
	for(int i=1;i<=n;i++)read(w[i]),q.push(ming(w[i],0));
	while((n-1)%(k-1)!=0) n++,q.push(ming(0,0));
	while(n>1){
		LL sum=0,maxx=0;
		for(int i=1;i<=k;i++){
			ming t=q.top();q.pop();
			maxx=max(maxx,t.dep);sum+=t.val;
		}
		q.push(ming(sum,maxx+1));
		ans+=sum;n-=(k-1);
	}
	printf("%lld\n%lld",ans,q.top().dep);
	//while(!q.empty())q.pop();
	return 0;
}

谢谢!!!

posted @ 2019-12-21 15:37  StaroForgin  阅读(7)  评论(0)    收藏  举报  来源