uva 10954 Huffman

//============================================================================
// Name        :
// Author      : Count_24
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdlib>
#include <cctype>
#define M 110
#define INF 0xfffffff
#define EXP 1e-8


using namespace std;


//最小优先级队列


int a[M];
int heap_size; // 元素的个数
int num_array;


int PARENT(int i){return i/2;}
int LEFT(int i)  {return 2*i;}
int RIGHT(int i) {return 2*i+1;}


int sum;


void Exchange(int i,int j){  int temp; temp = a[i]; a[i] = a[j]; a[j] = temp;}


void MIN_HEAPIFY(int a[],int i) // 保持堆的性质
{
    int l,r,smallest;
    l = LEFT(i);
    r = RIGHT(i);
    if(l <= heap_size && a[l] < a[i])
        smallest = l;
    else smallest = i;
    if(r <= heap_size && a[r] < a[smallest])
        smallest = r;
    if(smallest != i){
        Exchange(i,smallest);
        MIN_HEAPIFY(a,smallest);
    }
}


void BUILD_MIN_HEAP(int a[])  //建堆  优先队列
{
    heap_size = num_array; //元素的个数
    for(int i = heap_size/2;i >= 1;i--)
        MIN_HEAPIFY(a,i);
}


int HEAP_MINIMUM(int a[]){return a[1];} //取最小值


int HEAP_EXTRACT_MIN(int a[]){  //取出最小值  并保持状态
int cmin = a[1];
a[1] = a[heap_size];
heap_size--;
MIN_HEAPIFY(a,1);
return cmin;
}




void HEAP_INCREASE_KEY(int a[],int i,int key){  //在最小堆的基础上  第 i 个位置 插入新的元素
a[i] = key;
while(i > 1 && a[i/2] > a[i]){
Exchange(i,i/2);
i = i/2;
}
}


void MIN_HEAP_INSERT(int a[],int key){ //在最后一个位置 插入元素 并保持堆的性质
heap_size = heap_size + 1;
a[heap_size] = INF;
HEAP_INCREASE_KEY(a,heap_size,key); // 在最后添加一个元素 并插入
}




int main() {
//freopen("in.in","r",stdin);


while(cin>>num_array && num_array){
sum = 0;
for(int i = 1;i <= num_array;i++)
cin>>a[i];
BUILD_MIN_HEAP(a);


int x,y,z;
for(int k = 1;k < num_array;k++){
x = HEAP_EXTRACT_MIN(a);
y = HEAP_EXTRACT_MIN(a);
z = x + y;
sum += z;
MIN_HEAP_INSERT(a,z);
}
cout<<sum<<endl;
}


return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值