标签: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