BZOJ4198或UOJ130 荷马史诗 【K叉哈夫曼树】【堆】

来源:互联网 发布:高中生电脑编程培训 编辑:程序博客网 时间:2024/04/28 01:31

题目链接:
http://www.lydsy.com/JudgeOnline/problem.php?id=4198
http://uoj.ac/problem/130

题解:
用一个堆来维护一个K叉哈夫曼树,如果无法合并(即n-1不为k-1的倍数时),就补充n-k个虚拟节点,节点的权值为0(不会影响结果),再合并即可。

代码:

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <queue>using namespace std;typedef long long LL;const int inf = 1 << 26;struct trees {    LL v, h;};bool operator<(trees a, trees b){    if(a.v != b.v) return a.v > b.v;    return a.h > b.h;   }priority_queue<trees> q;int n, k;int main(){    scanf("%d %d", &n, &k);    for ( int i = 1; i <= n; i ++ ) {        trees a;        scanf("%lld", &a.v);        a.h = 1;        q.push(a);    }    LL top = 0;    if((n-1)%(k-1) != 0) top += k-1-(n-1)%(k-1);    // 需要补为 0 的结点的个数    for ( int i = 1; i <= top; i ++ ) {        trees need;        need.v = 0; need.h = 1;        q.push(need);    }     top += n;    LL ans = 0;    while(top != 1) {        trees a;        LL temp = 0, mx = 0;        for ( int i = 1; i <= k; i ++ ) {            a = q.top(); temp += a.v;            mx = max(mx, a.h); q.pop();        }        ans += temp;        a.v = temp; a.h = mx+1;        q.push(a);        top -= k-1;    }    printf("%lld\n%lld\n", ans, q.top().h-1);    return 0;}
1 0
原创粉丝点击