/*
问题:霍夫曼树
输入:第一行,输入一个数n,为叶节点个数,节点有权值weight
输出:所有节点的值与权值的乘积之和,2<=1000,weight<=100
输入:
5
1 2 2 5 9
输出:
37
思路:K个节点
K>=2,每次取最小值和次最小值,构成新节点,再放入
K=1,该节点为根节点,结束循环
关键:
1使用小顶堆,用priority_queue<int,vector<int>,qreater<int> >Q,以前使用<,将最小的放在前面
使用greater,即>,会将最大的放在前面,导致大顶堆
2使用权值累加:iSumWeight += iMin + iMin1
3要将新生成的节点放入到优先级队列中
*/
#include <stdio.h>
#include <stdlib.h>
#include <queue>
#include <memory.h>
using namespace std;
int main(int argc,char* argv[])
{
int iNum;
while(EOF!=scanf("%d",&iNum) && 2 <= iNum && iNum <= 1000)
{
priority_queue<int,vector<int>,greater<int> > Q;
//做判空处理,如果为空先清空
if(!Q.empty())
{
Q.pop();
}
//int *Arr = (int*)malloc(iNum*sizeof(int));
int iValue;
for(int i = 0 ;i < iNum ; i++)
{
scanf("%d",&iValue);
if(iValue <= 100)
{
Q.push(iValue);
}
else
{
printf("The weight you input is wrong!");
}
//*(Arr + i) = iValue;
}
//进行堆操作,int count = 1,利用权值累加,例如:1,2,2 = (1+2) + 2 + 3,其中第一次的1 + 2已经累加了
int iSumWeight = 0;
while(1 < Q.size())
{
int iMin = Q.top();
Q.pop();
int iMin2 = Q.top();
Q.pop();
iSumWeight += iMin + iMin2;
//把新的节点放入
Q.push(iMin + iMin2);
}
printf("%d",iSumWeight);
}
system("pause");
getchar();
return 0;
}