Cod sursa(job #481975)

Utilizator marius21Marius Petcu marius21 Data 2 septembrie 2010 10:49:17
Problema Coduri Huffman Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.64 kb
#include <cstdio>
#include <cstdlib>

typedef struct _nod
{
	int val;
	_nod * t;
	int branch;
} nod;


nod * hp[1000000];
int nhp;

void hp_swap(int a, int b)
{
	nod * aux = hp[a];
	hp[a]=hp[b];
	hp[b]=aux;
}

void hp_up(int i)
{
	while (i)
	{
		int pos = ((i+1)>>1)-1;
		if (hp[i]->val>=hp[pos]->val)
			break;
		hp_swap(i,pos);
		i=pos;
	}
}

void hp_down(int i)
{
	while (1)
	{
		int p1=(i<<1)+1;
		int p2=(i<<1)+2;
		int min=i;
		if ((p1<nhp)&&(hp[p1]->val<hp[min]->val))
			min=p1;
		if ((p2<nhp)&&(hp[p2]->val<hp[min]->val))
			min=p2;
		if (min==i)
			break;
		hp_swap(min,i);
		i=min;
	}
}

nod * hp_popmin()
{
	nod * res = hp[0];
	hp_swap(0,--nhp);
	hp_down(0);
	return res;
}

void hp_push(nod * val)
{
	hp[nhp++]=val;
	hp_up(nhp-1);
}


FILE *fin=fopen("huffman.in","r");
FILE *fout=fopen("huffman.out","w");

nod a[1000000];
long long b[1000000];
int lg[1000000];

int main (int argc, char * const argv[]) {
	int n;
    fscanf(fin, "%d", &n);
	nhp=n;
	for (int i=0; i<n; i++)
	{
		fscanf(fin, "%d", &a[i].val);
		a[i].t=NULL;
		hp[i]=a+i;
	}
	for (int i=0; i<n-1; i++)
	{
		nod * min1 = hp_popmin();
		nod * min2 = hp_popmin();
		min1->branch=0;
		min2->branch=1;
		nod * tata = new nod;
		tata->val=min1->val+min2->val;
		tata->t=NULL;
		min1->t=tata;
		min2->t=tata;
		hp_push(tata);
	}
	long long sum=0;
	for (int i=0; i<n; i++)
	{
		nod * p = &a[i];
		int lng=0;
		long long nr=0;
		while (p->t)
		{
			lng++;
			nr=((nr<<1)|(p->branch));
			p=p->t;
		}
		if (!lng)
			lng=1;
		b[i]=nr;
		lg[i]=lng;
		sum+=lng*(a[i].val);
	}
	fprintf(fout, "%lld\n",sum);
	for (int i=0; i<n; i++)
		fprintf(fout, "%d %lld\n",lg[i],b[i]);
	fclose(fin);
	fclose(fout);
    return 0;
}