Cod sursa(job #1161323)

Utilizator SilverGSilver Gains SilverG Data 31 martie 2014 10:22:06
Problema Coduri Huffman Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.86 kb
/*
	Keep It Simple!
*/

#include<cstdio>
#include<list>

using namespace std;

#define MaxN 1000005

struct node
{
	node* left,*right;
	int value,idx;

	node() {
		left = right = NULL;
		value = idx = 0;
	};

}*root;

list<node*> SingleQueue,MergeQueue;
int Level[MaxN];
long long Value[MaxN];
int N,x;
long long Sum;

node* GetMin()
{
	if(SingleQueue.size()&& ( !MergeQueue.size() || SingleQueue.front()->value<=MergeQueue.front()->value))
		{
				node* aux = SingleQueue.front();
				SingleQueue.pop_front();
				return aux;
		}
	else if( MergeQueue.size() && ( !SingleQueue.size() || SingleQueue.front()->value>MergeQueue.front()->value))
		{
				node* aux = MergeQueue.front();
				MergeQueue.pop_front();
				return aux;
		}
}

void BuildHuffManTree()
{
	while(SingleQueue.size() + MergeQueue.size() > 1)
	{
		node *FirstMin = GetMin();
		node *SecondMin = GetMin();

		node* aux = new node;
		aux ->left = FirstMin;
		aux ->right = SecondMin;
		aux ->value = FirstMin->value + SecondMin -> value;
		MergeQueue.push_back(aux);
	}
	if(SingleQueue.size() == 1)
		root = SingleQueue.front();
	else
		root = MergeQueue.front();
}

void DFS(node* nod,int level,int value)
{
	if( !nod-> left && !nod->right)
	{
		Level[nod->idx] = level;
		Value[nod->idx] = value;
		return;
	}
	Sum += nod->value;
	if( nod->left )
		DFS(nod->left,level+1,value*2);
	if( nod->right )
		DFS(nod->right,level+1,value*2+1);
}

int main()
{
	freopen("huffman.in","r",stdin);
	freopen("huffman.out","w",stdout);

	scanf("%d",&N);

	for(int i=1;i<=N;i++)
	{
		scanf("%d",&x);
		node *aux = new node;
		aux->left = aux->right = NULL;
		aux->value = x;
		aux->idx = i;
		SingleQueue.push_back(aux);
	}

	BuildHuffManTree();
	DFS(root,0,0);

	printf("%lld\n",Sum);
	for(int i=1;i<=N;i++)
		printf("%d %lld\n",Level[i],Value[i]);
}