学了哈夫曼树这道题还是好想的,基本上和构造哈夫曼树的思路一样,但是题目要求最长si的最小值,所以用两个关键字的堆,第一关键字是把出现次数作为权值,第二关键字表示从该节点开始的最长长度,权值相同时,选择长度较小的合并。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 struct node{ 5 ll num,dep; 6 //node(){} 7 node(ll a,ll b){num=a,dep=b;} 8 bool operator < (const node &a) const { 9 if(num==a.num) return a.dep<dep; 10 else return a.num<num; 11 } 12 }; 13 14 priority_queue<node> q; 15 ll k,n,ans,cnt; 16 17 int main(){ 18 scanf("%lld%lld",&n,&k); 19 for(int i=1;(ll)i<=n;i++){ 20 ll temp; 21 scanf("%lld",&temp); 22 q.push(node(temp,0));//将出现的次数都当做权值,做哈夫曼 23 } 24 cnt=n; 25 if((n-1)%(k-1)) cnt+=(k-1-(n-1)%(k-1));//补点 26 for(int i=n+1;(ll)i<=cnt;i++) 27 q.push(node(0,0));//插入新补的点 28 while(cnt>1){ 29 ll sum=0,len=0; 30 for(int i=1;(ll)i<=k;i++){ 31 sum+=q.top().num; 32 len=max(len,q.top().dep); 33 q.pop(); 34 } 35 q.push(node(sum,len+1)); 36 cnt=cnt-k+1; 37 ans+=sum; 38 } 39 printf("%lld\n",ans); 40 printf("%lld\n",q.top().dep); 41 }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。