#include #include using namespace std; const int MAXN=20010; int r[MAXN]; int n,m,x; void Sink(int k,int n)//下沉操作,小顶堆 { while(2*k<=n)//如果有左孩子 { int j=2*k;//j指向左孩子 if(jr[j+1])//如果有右孩子且左孩子比右孩子小 j++; //j指向右孩子 if(r[k]<=r[j])//比较大的孩子大 break; //已满足堆 else swap(r[k],r[j]);//与较大的孩子交换 k=j;//k指向交换后的新位置,继续向下比较,一直下沉到叶子 } } void CreatHeap(int n)//构建初始堆 { for(int i=n/2;i>0;i--)//从最后一个分支结点n/2开始调整为堆,直到第一个结点 Sink(i,n); } int main() { int n,Min; long long ans=0; while(scanf("%d",&n)!=EOF) { for(int i=1;i<=n;i++) scanf("%d",&r[i]); CreatHeap(n);//构建初始堆 while(n>1) { Min=r[1]; r[1]=r[n--]; Sink(1,n);//堆顶下沉 Min+=r[1]; r[1]=Min; Sink(1,n);//堆顶下沉 ans+=Min; } printf("%I64d\n",ans); } return 0; }