Cod sursa(job #843321)

Utilizator AnteusPatrascoiu Mihai Anteus Data 27 decembrie 2012 19:49:16
Problema Coduri Huffman Scor 65
Compilator cpp Status done
Runda Arhiva educationala Marime 1.99 kb
#include <stdio.h>
#include <queue>
#include <vector>
#include <algorithm>
#include <string.h>
#define NMAX 100005
using namespace std;
struct nod {  int ord,val;
			  nod *st,*dr; } *p,*root, *aux;
struct code { int ord,cost;
			  long long val; } t;
vector < code > v;
long long lg;
int n;

class cmp
{
public:
	
	bool operator() (const nod &A, const nod &B)
	{
		return (A.val > B.val);
	}
};

priority_queue < nod, vector < nod >, cmp > pq;

const bool compare (const code &a, const code &b)
{
	return (a.ord < b.ord);
}
	
void read()
{
	scanf ("%d", &n);
	
	for (int i=1;i<=n;i++)
	{
		p = new nod;
		
		p->st = NULL;	p->dr = NULL;	p->ord = i;
		
		scanf ("%d", &p->val);
		
		pq.push(*p);
	}
}

int numar(char *s)
{
	int k=0,l=strlen(s);
	
	for (int i=0;i<l;i++)
	{
		k = k + (s[i]-'0');
		k = k<<1;
	}
	
	return k;
}

void huffman_code(int S)
{
	while ( S > 1 )
	{
		p = new nod;

		aux = new nod;	
		*aux = pq.top();	pq.pop();
		p->st = aux;
		
		aux = new nod;
		*aux = pq.top();	pq.pop();
		p->dr = aux;
		
		p->val = p->st->val + p->dr->val;
		
		pq.push(*p);
		
		S--;
	}
	
	root = new nod;
	*root = pq.top();
}

void build(nod *p, int k, long long value, int length)
{
	if (k >= 0)
	{
		//s[k] =	(value)	?	'1'	:	'0';
		//s[k+1] = '\0';
		
		value = value<<1;
		value = value + k;
	}
	
	if ( (p->st == NULL) || (p->dr == NULL) )
	{
//		strcpy (t.a, s);
//		t.cost = strlen(s);
		
		t.cost = length;
		t.ord = p->ord;
		t.val = value;
		
		v.push_back(t);
		
		lg += t.cost * p->val;
		
		return;
	}
	
	build( p->st , 0, value, length+1 );
	build( p->dr , 1, value, length+1 );
}


int main()
{
	freopen ("huffman.in", "r", stdin);
	freopen ("huffman.out", "w", stdout);
	
	read();
	
	huffman_code(n);
	build(root, -1, 0, 0);
	
	sort (v.begin(), v.end(), compare);

	printf ("%lld\n", lg);
	for (unsigned int i=0;i<v.size();i++)
		printf ("%d %lld\n", v[i].cost, v[i].val);
	
	return 0;
}