zoukankan      html  css  js  c++  java
  • BZOJ 4198 荷马史诗

    哈夫曼树。

    如果要最大的深度最小,再按h排序即可。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #define maxv 100500
    #define maxe 1000500
    using namespace std;
    long long n,k,val[maxv*5],nume=0,g[maxv*5],tot,sum=0,dis[maxv*5],fath[maxv*5];
    struct edge
    {
        long long v,nxt;
    }e[maxe];
    struct status
    {
        long long val,pnt,h;
    };
    bool operator <(status x,status y)
    {
        if (x.val!=y.val) return x.val>y.val;
        return x.h>y.h;
    }
    priority_queue <status> q;
    void addedge(long long u,long long v)
    {
        e[++nume].v=v;
        e[nume].nxt=g[u];
        g[u]=nume;
    }
    void dfs(long long x)
    {
        for (long long i=g[x];i;i=e[i].nxt)
        {
            long long v=e[i].v;
            if (v!=fath[x])
            {
                fath[v]=x;dis[v]=dis[x]+1;
                dfs(v);
            }
        }
    }
    int max(int a,int b)
    {
        if (a>b) return a;
        return b;
    }
    int main()
    {
        scanf("%lld%lld",&n,&k);
        for (long long i=1;i<=n;i++)
        {
            scanf("%lld",&val[i]);
            status s;
            s.pnt=i;s.val=val[i];s.h=0;
            q.push(s);
        }
        long long ret=0;
        while ((n+ret-1)%(k-1)!=0) ret++;
        for (long long i=1;i<=ret;i++)
        {
            status s;
            s.pnt=n+i;s.val=0;s.h=0;
            q.push(s);
            val[n+i]=0;
        }
        n+=ret;tot=n;
        long long ret1=0,ret2=0;
        while (q.size()>1)
        {
            sum=0;tot++;int mx=0;
            for (long long i=1;i<=k;i++)
            {
                status b=q.top();q.pop();
                sum+=b.val;mx=max(mx,b.h);
                addedge(b.pnt,tot);addedge(tot,b.pnt);
            }
            status s;
            s.pnt=tot;s.val=sum;s.h=mx+1;q.push(s);
            ret2=max(ret2,s.h);
            val[tot]=0;
        }
        dfs(tot);
        for (long long i=1;i<=n;i++)
            ret1+=val[i]*dis[i];
        printf("%lld
    %lld
    ",ret1,ret2);
        return 0;
    }
  • 相关阅读:
    python实现指定目录下批量文件的单词计数:串行版本
    PythonPP+lambda:示例
    python面向对象编程基础
    《平凡的世界》读后感
    代码
    【转】提高沟通效果的十个技巧
    LODOP中page-break-before:always给div分页
    LODOP超文本简短问答和相关内容
    Lodop打印较大的超出纸张的图片
    Lodop打印设计矩形重合预览线条变粗
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/5843456.html
Copyright © 2011-2022 走看看