参考blog:点击打开链接
题目1172:哈夫曼树
时间限制:1 秒
内存限制:32 兆
特殊判题:否
提交:8191
解决:3658
-
题目描述:
-
哈夫曼树,第一行输入一个数n,表示叶结点的个数。需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题目需要输出所有结点的值与权值的乘积之和。
-
输入:
-
输入有多组数据。
每组第一行输入一个数n,接着输入n个叶节点(叶节点权值不超过100,2<=n<=1000)。
-
输出:
-
输出权值。
-
样例输入:
-
5 1 2 2 5 9
-
样例输出:
-
37
-
来源:
基本思路就是建树,依次计算值
Code:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define maxvalue 0x7fffffff //0x7fffffff表示 long int的最大值
struct huffman
{
int weight;
int parent,lchild,rchild;
}list[5000];
int main()
{
int n,m;
int i,j;
int ans;
int x1,x2;
int m1,m2;
while(scanf("%d",&n)!=EOF)
{
m=2*n-1; //最多可能要用到2*n-1个节点
for(i=0;i<m;i++)
list[i].parent=list[i].lchild=list[i].rchild=-1; //初始化为-1
for(i=0;i<n;i++)
scanf("%d",&list[i].weight); //依次输入每个节点的值weight
ans=0;
for(i=0;i<n-1;i++)
{
x1=x2=0;
m1=m2=maxvalue;
for(j=0;j<n+i;j++)
{
if(list[j].weight<m1&&list[j].parent==-1) //如果小于当前最小的节点
{
x2=x1;
m2=m1;
x1=j;
m1=list[j].weight;
}
else if(list[j].weight<m2&&list[j].parent==-1) //如果大于当前最小节点但小于当前第二小节点
{
x2=j;
m2=list[j].weight;
}
}
list[x1].parent=n+i; //标记为已经有parent 也就是表示已经用过这个数
list[x2].parent=n+i;
list[n+i].lchild=x1;
list[n+i].rchild=x2;
list[n+i].weight=list[x1].weight+list[x2].weight;
ans+=list[n+i].weight;
}
printf("%d\n",ans);
}
return 0;
}
不建树简单一点
Code:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int cmp(const void *a,const void *b)
{
return *(int *)a-*(int *)b;
}
int main()
{
int n,i,ans;
int a[5000];
while(scanf("%d",&n)!=EOF)
{
for(i=0;i<n;i++)
scanf("%d",&a[i]);
ans=0;
for(i=0;i<n-1;i++)
{
qsort(a+i,n-i,sizeof(a[0]),cmp);
ans+=(a[i]+a[i+1]);
a[i+1]+=a[i];
}
printf("%d\n",ans);
}
return 0;
}