您的位置:首页 > 理论基础

boj 1517 2010年计算机院复试 哈弗曼编码

2011-03-30 00:42 162 查看
题目大意(回忆版):哈夫曼树,第一行输入一个数n,表示叶结点的个数。需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题目需要输出所有结点的值与权值的乘积之和。

Sample:

Input:
5
1 2 2 5 9

Output:
37

解释:即生成如下图哈夫曼树,结点1的权值为4,结点2的权值为4,结点2的权值为3,结点5的权值为2,结点9的权值为1,和为37

#include<iostream>
using namespace std;
typedef struct
{
int weight,parent; //权值 父节点
}treenode;
treenode tree[1010];
treenode a;
int main()
{
int i,j,n,k,sum=0,temp,minone=1001,mintwo=1001,minonep=-1,mintwop=-1,total,ceng=0;

scanf("%d",&n);
total=2*n-1;
for(i=1;i<=n;i++) //初始化
{
scanf("%d",&temp);
tree[i].weight=temp;
tree[i].parent=0;
}
temp=n;
for(i=n;i<total;i++) //初始时候parent都为0,如果成为叶子节点,则parent不再为0,所以用tree[j].parent条件控制
//minone mintwo,为第一小第二小两个数,
{
minone=mintwo=1001;
minonep=mintwop=-1;

for(j=1;j<=i;j++)
{
if(tree[j].parent==0)
{
if(tree[j].weight<minone) //如果权值比minone小,则minone传给mintwo,minone保持最小数
{
mintwo=minone;
mintwop=minonep;
minone=tree[j].weight;
minonep=j;
}
else
{
if(tree[j].weight<mintwo) //如果权值比minone大,但是比mintwo小,则赋值给mintwo
{
mintwo=tree[j].weight;
mintwop=j;
}

} //else

}
}
tree[i+1].weight=mintwo+minone; //两个最小权值节点成为新节点
tree[minonep].parent=i+1; //两个叶子节点的父节点为新节点
tree[mintwop].parent=i+1;

}

for(i=1;i<=n;i++) //如果parent不为0,则说明不是最高层节点,则递归到上一层,同时层数加1.
{
ceng=0;
a=tree[i];
while(a.parent!=0)
{
a=tree[a.parent];
ceng++;
}
sum=sum+ceng*tree[i].weight;
}
cout<<sum<<endl;
system("pause");

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: