[哈夫曼树] Jzoj P1736 扑克游戏
题解
- 典型哈夫曼树的结构
- 每次找两个跳,再将其和加入树
- 记录跳出去的和
代码
1 #include<iostream> 2 #include<iostream> 3 #include<cstdio> 4 #define INF 2147483647 5 #define N 20000 6 using namespace std; 7 long long dui[N*2+1],top; 8 void add(long x) 9 { 10 long now; 11 dui[++top]=x; 12 for (now=top;dui[now/2]>dui[now]&&now>1;now/=2) swap(dui[now],dui[now/2]); 13 } 14 long sum() 15 { 16 long ans=dui[1],now; 17 bool t=false; 18 dui[1]=INF; now=1; 19 while (!t) 20 { 21 t=true; 22 if (now*2==top||dui[now*2]<dui[now*2+1]) 23 { 24 if (dui[now]>dui[now*2]) 25 { 26 swap(dui[now],dui[now*2]); 27 now=now*2; 28 t=false; 29 } 30 } 31 else 32 if (now*2+1<=top) 33 if (dui[now]>dui[now*2+1]) 34 { 35 swap(dui[now],dui[now*2+1]); 36 now=now*2+1; 37 t=false; 38 } 39 } 40 return ans; 41 } 42 43 int main() 44 { 45 long n,m,x; 46 long long ans=0; 47 scanf("%ld",&n); 48 for (int i=1;i<=n;i++) 49 { 50 scanf("%ld",&x); 51 add(x); 52 } 53 for (int i=1;i<n;i++) 54 { 55 x=sum()+sum(); 56 ans+=x; 57 add(x); 58 } 59 printf("%lld\n",ans); 60 return 0; 61 }