Cod sursa(job #823166)

Utilizator mytzuskyMihai Morcov mytzusky Data 24 noiembrie 2012 18:13:41
Problema Coduri Huffman Scor 65
Compilator c Status done
Runda Arhiva educationala Marime 2.56 kb
#include "stdio.h"
#include "malloc.h"

#define swap(a,b) a=a+b, b=a-b, a=a-b

struct rezultat{
	long long cod, lg;
};

struct nodH{
	long long inf;
	long long ind;
};

struct nodA{
	long long inf;
	long long st, dr;
};

void SiftUp(struct nodH *h, long long n, long long i)
{
	if( i/2>0   &&  h[i/2].inf > h[i].inf)
	{
		swap(h[i].inf, h[i/2].inf);
		swap(h[i].ind, h[i/2].ind);
		SiftUp(&*h, n, i/2);
	}
}

void SiftDown(struct nodH *h, long long n, long long i)
{
	long long fiu=i;
	if(2*i <= n && h[fiu].inf > h[2*i].inf)
		fiu = 2*i;
	if(2*i+1 <= n && h[fiu].inf > h[2*i+1].inf)
		fiu = 2*i+1;

	if(fiu != i)
	{
		swap(h[i].inf, h[fiu].inf);
		swap(h[i].ind, h[fiu].ind);
		SiftDown(&*h,n,fiu);
	}
}

void MakeHeap(struct nodH *h, long long n)
{
	long long i;
	for(i=n/2;i>=1;i--)
		SiftDown(&*h,n,i);
}

void HeapSort(struct nodH *h, long long n)
{
	long long i,aux;
	MakeHeap(&*h,n);
	for(i=n;i>=2;i--)
	{
		swap(h[1].inf, h[i].inf);
		swap(h[1].ind, h[i].ind);

		SiftDown(&*h,i-1,1);
	}
}

void parc(struct nodA *a,struct rezultat *rez, long long x, long long cod, long long h)
{
	if(a[x].st != 0)
	{
		parc(a,&*rez, a[x].st, 2*cod  , h+1);
		parc(a,&*rez, a[x].dr, 2*cod+1, h+1);
		return;
	}
	rez[x].cod = cod;
	rez[x].lg = h;
}

int main()
{
	long long i, n, nn, Ni, min1, min2, ind1, ind2, S;
	struct nodA *a;
	struct nodH *h;
	struct rezultat *rez;

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

	scanf("%lld\n", &n);
	nn = n;
	Ni = n;
	S=0;



	h = (struct nodH*)calloc(Ni+1, sizeof(struct nodH));
	a = (struct nodA*)calloc(2*Ni, sizeof(struct nodA));
	

	for(i=1;i<=n;i++)
	{
		scanf("%lld\n", &h[i].inf);
		h[i].ind = i;

		a[i].inf = h[i].inf;
		a[i].st = 0; a[i].dr = 0;
		
	}

	while( n > 1 )
	{
		min1 = h[1].inf;
		ind1 = h[1].ind;
		h[1].inf = h[n].inf; h[1].ind = h[n].ind;
		h[n].inf = -1; h[n].ind = -1;
		n--;
		SiftDown(&*h,n,1);
		

		min2 = h[1].inf;
		ind2 = h[1].ind;
		h[1].inf = h[n].inf; h[1].ind = h[n].ind;
		h[n].inf = -1; h[n].ind = -1;
		n--;
		SiftDown(&*h,n,1);
		
		n++;
		h[n].inf = min1 + min2;
		h[n].ind = nn+1;
		SiftUp(&*h,n,n);


		nn++;
		a[nn].inf = min1+min2;
		a[nn].st = ind1;
		a[nn].dr = ind2;

	}

	for(i=1;i<=nn;i++)
		if(a[i].st != 0)
			S += a[i].inf;
	printf("%lld\n", S);

	free(h);

	rez = (struct rezultat*)calloc(Ni+1, sizeof(struct rezultat));
	parc(a,rez, nn, 0, 0);

	for(i=1;i<=Ni;i++)
		printf("%lld %lld\n", rez[i].lg, rez[i].cod);
	free(a);
	free(rez);
	
	return 0;
}