Cod sursa(job #823159)

Utilizator mytzuskyMihai Morcov mytzusky Data 24 noiembrie 2012 18:03:04
Problema Coduri Huffman Scor 65
Compilator c Status done
Runda Arhiva educationala Marime 2.47 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 nod{
	long long inf;
	long long ind;
	char c;
	long long st, dr;
};

void SiftUp(struct nod *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 nod *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 nod *h, long long n)
{
	long long i;
	for(i=n/2;i>=1;i--)
		SiftDown(&*h,n,i);
}

void HeapSort(struct nod *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 nod *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 nod *a, *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 nod*)calloc(n+1, sizeof(struct nod));
	a = (struct nod*)calloc(2*n, sizeof(struct nod));
	rez = (struct rezultat*)calloc(n+1, sizeof(struct rezultat));

	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);

	parc(a,rez, nn, 0, 0);

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

	return 0;
}