Cod sursa(job #598115)

Utilizator sima_cotizoSima Cotizo sima_cotizo Data 24 iunie 2011 16:34:11
Problema Coduri Huffman Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.55 kb
#include <vector>
#include <queue>
#include <cstdio>
using namespace std;
#define MAX 1000010

struct node
{
	node *left, *right;
	int c;
	long long weight;
};

deque<node*> Q, Q2;
int length[MAX], N;
long long total, code[MAX];

void df(node *r, long long c, int d)
{
	if ( r->c > 0 )
	{
		code[r->c] = c;
		length[r->c] = d;
		total += r->weight * d;
		return ;
	}
	if ( r->left )
		df(r->left, c*2, d+1);
	if ( r->right )
		df(r->right, c*2 + 1, d+1);
}

node* take_elem()
{
	node* a;
	if ( Q2.empty() )
	{
		a = *(Q.begin());
		Q.pop_front();
	}
	else if ( Q.empty() )
	{
		a = *(Q2.begin());
		Q2.pop_front();
	}
	else
	{
		if ( (*(Q.begin()))->weight < (*(Q2.begin()))->weight )
		{
			a = *(Q.begin());
			Q.pop_front();
		}
		else
		{
			a = *(Q2.begin());
			Q2.pop_front();
		}
	}
	return a;
}

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

	scanf("%d", &N);
	for (int i=1; i<=N; ++i)
	{
		node *p = new node;
		scanf("%lld", &p->weight);
		p->c = i;
		p->left = p->right = NULL;
		Q.push_back(p);
	}

	while ( Q.size()+Q2.size() > 1 )
	{
		node *a = take_elem();
		node *b = take_elem();
		
		node *c = new node;
		c -> weight = a->weight + b->weight;
		c -> c = -1;
		c -> left = a;
		c -> right = b;
		Q2.push_back(c);
	}

	node *root = *(Q2.begin());
	df(root, 0, 0);

	printf("%lld\n", total);
	for (int i=1; i<=N; ++i)
	{
		printf("%d %lld", length[i], code[i]);
		
/*		printf(" = ");
		if ( code[i] == 0 )
			printf("0");
		for (int j=1; j<=code[i]; j<<=1)
			printf("%d", code[i] & j ? 1 : 0);
*/
		printf("\n");
	}
	return 0;
}