首页 > 代码库 > BZOJ 4198 荷马史诗

BZOJ 4198 荷马史诗

哈夫曼树。

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

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#define maxv 100500#define maxe 1000500using 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\n%lld\n",ret1,ret2);    return 0;}

 

BZOJ 4198 荷马史诗