http://ybt.ssoier.cn:8088/problem_show.php?pid=1369
写法一:手写优先队列
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int MAX_N=30005; 4 int h[MAX_N];//用来存放堆的数组 5 int sz=0;//用来存储堆中元素的个数,也就是堆的大小 6 int n; 7 long long ans; 8 void push(int x) 9 { 10 int i=++sz;//自己节点的编号 11 while(i){ 12 int p= i / 2;//父亲节点的编号 13 if( h[p] <= x) break;//无需交换 14 //把父亲节点的数值放下来,而把自己提上去 15 h[i] = h[p]; 16 i = p; 17 } 18 h[i] = x; 19 } 20 int pop() 21 { 22 //最小值 23 int ret = h[1]; 24 //要提到根的值 25 int x = h[sz]; 26 //从根开始向下交换 27 int i=1; 28 while(i*2 + 1 <= sz) 29 { 30 //比较儿子的值 31 int l=i*2, r=i*2+1; 32 33 if(r <= sz && h[r] < h[l])l=r; 34 //如果没有大小颠倒则退出 35 if(h[l] >= x)break; 36 //把儿子的数值提上来 37 h[i] = h[l]; 38 i = l; 39 } 40 h[i] = x; 41 sz--; 42 return ret; 43 } 44 void testprint() 45 { 46 for(int i=1; i<=sz; i++) 47 cout<<h[i]<<" "; 48 cout<<endl; 49 } 50 int main() 51 { 52 53 scanf("%d",&n); 54 for(int i=1; i<=n; i++){ 55 int x; 56 cin>>x; 57 push(x); 58 } 59 //testprint(); 60 61 for(int i=1; i<n; i++){ 62 int t1=pop(), t2=pop(); 63 ans+=t1+t2; 64 push(t1+t2); 65 } 66 printf("%lld",ans); 67 68 return 0; 69 }
写法二:STL
1 #include <bits/stdc++.h> 2 using namespace std; 3 int n; 4 priority_queue<int, vector<int>, greater<int> >h; 5 long long ans; 6 int main() 7 { 8 9 scanf("%d",&n); 10 for(int i=1; i<=n; i++){ 11 int x; 12 cin>>x; 13 h.push(x); 14 } 15 //testprint(); 16 17 for(int i=1; i<n; i++){ 18 int t1=h.top(); h.pop(); 19 int t2=h.top(); h.pop(); 20 ans+=t1+t2; 21 h.push(t1+t2); 22 } 23 printf("%lld",ans); 24 25 return 0; 26 }
或者写法三:STL
1 #include <bits/stdc++.h> 2 using namespace std; 3 int n; 4 priority_queue<int>h; 5 long long ans; 6 int main() 7 { 8 9 scanf("%d",&n); 10 for(int i=1; i<=n; i++){ 11 int x; 12 cin>>x; 13 h.push(-x); 14 } 15 //testprint(); 16 17 for(int i=1; i<n; i++){ 18 int t1=-h.top(); h.pop(); 19 int t2=-h.top(); h.pop(); 20 ans+=t1+t2; 21 h.push(-(t1+t2)); 22 } 23 printf("%lld",ans); 24 25 return 0; 26 }
printf("%lld",ans);