您的位置:首页 > 其它

九度OJ1172:哈夫曼树

2016-03-12 16:25 375 查看
[b]来源:[/b]
[b]http://ac.jobdu.com/problem.php?pid=1172[/b]
题目描述:

哈夫曼树,第一行输入一个数n,表示叶结点的个数。需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题目需要输出所有结点的值与权值的乘积之和。
输入:



输入有多组数据。

每组第一行输入一个数n,接着输入n个叶节点(叶节点权值不超过100,2<=n<=1000)。
输出:

输出权值。
样例输入:
5
1 2 2 5 9

样例输出:
37


方法一:构建Haffman Tree, 然后计算叶节点的权值。

<pre name="code" class="cpp">#include <stdio.h>
#include <algorithm>

using namespace std;

struct Node
{
int e;
Node *lchild, *rchild;
};

bool cmp(Node *a, Node *b)
{
return a->e < b->e;
}

Node *arr[100];

int CreateHaffmanTree(int n)
{
int i=0;
while(i<n-1)
{
Node *root = (Node*)malloc(sizeof(Node));
root->lchild = arr[i];
root->rchild = arr[i+1];
root->e = arr[i]->e + arr[i+1]->e;
arr[++i] = root;
sort(arr+i,arr+n,cmp);
}
return 0;
}
int countHaffmanTree(Node *root, int level)
{
if(root->lchild || root->rchild)
{
return countHaffmanTree(root->lchild, level+1)+
countHaffmanTree(root->rchild, level+1);
}
else return root->e * level;
}

int main()
{
freopen("in.txt", "r", stdin);
int n,e;
scanf("%d",&n);
for(int i=0; i<n; i++)
{
scanf("%d",&e);
Node *root = (Node*)malloc(sizeof(Node));
root->e = e;
root->lchild = NULL;
root->rchild = NULL;
arr[i] = root;
}
sort(arr, arr+n, cmp);
CreateHaffmanTree(n);
printf("%d\n",countHaffmanTree(arr[n-1], 0));
return 0;
}
方法二:不建树,每次吧排序后最小的两个值加入权值和,将还未统计过的值和新产生的值(最小的两个数的和)重新排序。
<pre name="code" class="cpp">
7e82
#include <stdio.h>
#include <algorithm>

using namespace std;

int main()
{
freopen("in.txt","r",stdin);
int n, sum = 0;
int arr[100];
scanf("%d",&n);
for(int i=0; i<n; i++)
{
scanf("%d",&arr[i]);
}
sort(arr,arr+n);
i = 0;
while(i<n-1)
{
sum+= arr[i]+arr[i+1];
arr[i+1] = arr[i]+arr[i+1];
i++;
sort(arr+i,arr+n);
}
for(i=0; i<n; i++)
printf("%d ",arr[i]);
printf("%d ",sum);
return 0;
}



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