Cod sursa(job #1161358)

Utilizator SilverGSilver Gains SilverG Data 31 martie 2014 10:43:26
Problema Coduri Huffman Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 1.92 kb
/*
	Keep It Simple!
*/

#include<cstdio>
#include<list>

using namespace std;

#define MaxN 1000005

struct nod
{
	int left,right;
	long long value;

}Nodes[2*MaxN];

int SingleQueue[MaxN],MergeQueue[MaxN];
int SingleBegin,MergeEnd,SingleEnd,MergeBegin;
int Level[MaxN];
long long Value[MaxN];
int N,x,NumberOfNodes;
long long Sum;
int root;

int GetMin()
{
	if((SingleEnd-SingleBegin)&& ( !(MergeEnd-MergeBegin) || Nodes[SingleQueue[SingleBegin]].value<=Nodes[MergeQueue[MergeBegin]].value))
		{
				int aux = SingleQueue[SingleBegin++];
				return aux;
		}
	else if( (MergeEnd-MergeBegin) && ( !(SingleEnd-SingleBegin) || Nodes[SingleQueue[SingleBegin]].value>Nodes[MergeQueue[MergeBegin]].value))
		{
				int aux = MergeQueue[MergeBegin++];
				return aux;
		}
}

void BuildHuffManTree()
{
	while( (SingleEnd-SingleBegin) + (MergeEnd-MergeBegin) > 1)
	{
		int FirstMin = GetMin();
		int SecondMin = GetMin();
		Nodes[++NumberOfNodes].left = FirstMin;
		Nodes[NumberOfNodes].right = SecondMin;
		Nodes[NumberOfNodes].value = Nodes[FirstMin].value + Nodes[SecondMin].value;
		MergeQueue[MergeEnd++]=NumberOfNodes;
	}
	if(SingleEnd-SingleBegin == 1)
		root = SingleQueue[SingleBegin];
	else
		root = MergeQueue[MergeBegin];
}

void DFS(int nod,int level,int value)
{
	if( !Nodes[nod].left && !Nodes[nod].right)
	{
		Level[nod] = level;
		Value[nod] = value;
		return;
	}
	Sum += Nodes[nod].value;
	if( Nodes[nod].left )
		DFS(Nodes[nod].left,level+1,value*2);
	if( Nodes[nod].right )
		DFS(Nodes[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);
		Nodes[++NumberOfNodes].value = x;
		SingleQueue[SingleEnd++] = i;
	}

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

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