九度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;
}


 


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