Cod sursa(job #1087703)

Utilizator roby2001Sirius roby2001 Data 19 ianuarie 2014 19:20:02
Problema Coduri Huffman Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 2.28 kb
/*
          ~Keep It Simple!~
*/

#include<stdio.h>

#define NMax 1000005

struct node
{
	int nrc;
	long long val;
	node *left,*right,*next;

	node()
	{
		nrc = val = 0;
		left = right = next = NULL;
	}

};

node *SingleQueue,*MergeQueue;
node *Root;

int N;
long long FinalLg[NMax],FinalVal[NMax],S;


void DF(node* nod,int level,long long val)
{
	if( nod->left == NULL)
	{
		FinalLg[nod->nrc] = level;
		FinalVal[nod->nrc] = val;
	}
	else
	{
		S += nod->val;
		DF(nod->left,level+1,val*2);
		DF(nod->right,level+1,val*2+1);
	}
}

void push_back(node *&Queue, int x, int nrc )
{
	node* p = new node();
	p->val = x;
	p->nrc = nrc;
	p->left = p->right = p->next = NULL;

	if(!Queue)
		Queue = p;
	else
	{
		node* q;
		for(q = Queue; q->next != NULL; q = q->next);
		q->next = p;
	}
}

node* MinVal()
{
	if(!SingleQueue)
		return MergeQueue;
	else if(!MergeQueue)
		return SingleQueue;
	else if(SingleQueue->val <= MergeQueue->val)
		return SingleQueue;
	else
		return MergeQueue;
}

void pop_front(node *&Queue)
{
	node* p = Queue;
	Queue = Queue->next;
}

void push_back_node(node *&Queue, node* aux)
{
	node *p;
	if( !Queue )
		Queue = aux;
	else
	{
	for(p = Queue; p->next != NULL; p = p->next);
	p->next = aux;
	}
}

void BuildTree()
{
	while( SingleQueue || MergeQueue )
	{
		if( SingleQueue && !SingleQueue->next && !MergeQueue)
		{
			Root = SingleQueue;
			break;
		}
		else if( !SingleQueue && !MergeQueue->next)
		{
			Root = MergeQueue;
			break;
		}

		node *x = MinVal();

		if( x == SingleQueue)
			pop_front(SingleQueue);
		else
			pop_front(MergeQueue);

		node *y = MinVal();

		if( y == SingleQueue)
			pop_front(SingleQueue);
		else
			pop_front(MergeQueue);

		x->next = y->next = NULL;

		node *R = new node();
		R->left = x;
		R->right = y;
		R->val = x->val + y->val;
		R->next = NULL;
		push_back_node(MergeQueue,R);
	}
}

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

	scanf("%d",&N);

	int x;

	for(int i=1; i<=N; i++)
	{
		scanf("%d",&x);
		push_back(SingleQueue,x,i);
	}

	BuildTree();

	DF(Root,0,0);

	printf("%lld\n",S);

	for(int i=1; i<=N; i++)
		printf("%lld %lld\n",FinalLg[i],FinalVal[i]);

	return 0;
}