标签:sgu
题目大意:但是如何用小根堆做呢?我们观察一下huffman tree 的权值,会发现也等于每个节点的权值和,根据这个道理,我们可以当小根堆中的元素个数大于1时,将最小的两个合并成一个,权值相加,然后将这个点重新插入堆中,ans+=v[i]+v[j](两个合并的权值),然后当只剩下一个元素的时候就跳出循环输出ans就行了
AC代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
long long a[500010]={0};
long long ans=0;
int n;
void tz(int k)
{
long long p=(long long)2e19,q=(long long)2e19;
if(k*2<=n) p=a[k*2];
if(k*2+1<=n) q=a[k*2+1];
if(p<=q && p<=a[k])
{
swap(a[k],a[k*2]);
tz(k*2);
}
else if(q<=p && q<=a[k])
{
swap(a[k*2+1],a[k]);
tz(k*2+1);
}
return;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
scanf("%I64d",&a[i]);
sort(a+1,a+n+1);
for(;n>1;)
{
long long x1=a[1];
swap(a[1],a[n]);
n--;
tz(1);
long long x2=a[1];
ans+=x1+x2;
a[1]=x1+x2;
tz(1);
}
printf("%I64d\n",ans);
return 0;
}标签:sgu
原文地址:http://blog.csdn.net/qq_21995319/article/details/42122683