bzoj4198 noi2015 荷马史诗

来源:互联网 发布:linux corosync 编辑:程序博客网 时间:2024/06/11 21:15

k叉哈夫曼树,平衡整颗树即可

然后开个双队列由小到大做

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<algorithm>#define LL long long#define fo(i,a,b) for(int i=a;i<=b;i++)#define efo(i,x) for(int i=last[x];i!=0;i=e[i].next)using namespace std;inline LL read(){LL d=0,f=1;char s=getchar();while(s<'0'||s>'9'){if(s=='-')f=-1;s-getchar();}while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}return d*f;}#define N 100005LL a[N],w[N];int n,m;struct edge{LL num,dep;}sta1[N],sta2[N];LL h1=1,h2=1,t1,t2=0;edge get(){if(h2>t2)return sta1[h1++];if(h1>t1)return sta2[h2++];if(sta1[h1].num==sta2[h2].num){if(sta1[h1].dep<sta2[h2].dep)return sta1[h1++];else return sta2[h2++];}if(sta1[h1].num<sta2[h2].num)return sta1[h1++];else return sta2[h2++];}void add(LL x,int de){sta2[++t2].num=x;sta2[t2].dep=de;}void check(){cout<<"New:\n";cout<<h1<<' '<<t1<<' '<<h2<<' '<<t2<<endl;cout<<"stack1.num:";fo(i,h1,t1)cout<<sta1[i].num<<' ';cout<<endl;cout<<"stack1.dep:";fo(i,h1,t1)cout<<sta1[i].dep<<' ';cout<<endl;cout<<"stack2.num:";fo(i,h2,t2)cout<<sta2[i].num<<' ';cout<<endl;cout<<"stack2.dep:";fo(i,h2,t2)cout<<sta2[i].dep<<' ';cout<<endl;}int main(){memset(w,0,sizeof(w));n=read();m=read();fo(i,1,n)w[i]=read();while((n-1)%(m-1)!=0)n++;sort(w+1,w+n+1);fo(i,1,n){sta1[i].num=w[i];sta1[i].dep=0;}int cnt=n,dep=1;t1=n;LL ans=0;while(cnt!=1){LL ret=0,len=0;fo(i,1,m){edge t=get();ret+=t.num,cnt--;len=max(len,t.dep);}ans+=ret;add(ret,len+1);cnt++;//check();}cout<<ans<<endl<<sta2[h2].dep<<endl;return 0;}


0 0
原创粉丝点击