九度OJ1172 哈夫曼树

来源:

http://ac.jobdu.com/problem.php?pid=1172

题目描述:

哈夫曼树,第一行输入一个数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">#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;
}


 


 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章