Cod sursa(job #426034)

Utilizator otilia_sOtilia Stretcu otilia_s Data 26 martie 2010 13:04:36
Problema Coduri Huffman Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 1.26 kb
#include <cstdio>
using namespace std;
#define NMAX 1000006
struct caract
	{int ap, fs,fd;};
caract c[2*NMAX];
int n,Q1[NMAX],Q2[NMAX],lung[NMAX];
long long b[NMAX],sol;

void citire()
{
	freopen("huffman.in","r",stdin);
	scanf("%d",&n);
	int i;
	for (i=1;i<=n;++i)
	 {
		scanf("%d",&c[i].ap);	
		Q1[i]=i; c[i].fs=c[i].fd=0;
	 }	
}

int Min(int &st1, int dr1, int &st2, int dr2)
{
	if (st1>dr1) { ++st2; return Q2[st2-1];}
	if (st2>dr2) { ++st1; return Q1[st1-1];}
	if (c[Q1[st1]].ap<c[Q2[st2]].ap)
	   { ++st1; return Q1[st1-1];}
	++st2; return Q2[st2-1];
}

void dfs(int nod, int h, long long cod)
{
	if (c[nod].fs)
	   {
		dfs(c[nod].fs,h+1,cod<<1);
		dfs(c[nod].fd,h+1,(cod<<1)+1);
		return;
	   }
	lung[nod]=h;
	b[nod]=cod;
}

void afisare()
{
	freopen("huffman.out","w",stdout);
	printf("%lld\n",sol);
	int i;
	for (i=1;i<=n;++i)
	 printf("%d %lld\n",lung[i],b[i]);
}

int main()
{
	citire();
	int k,st1,dr1,st2,dr2,e1,e2; 
	
	k=n; sol=0;
	st1=st2=1; dr1=n; dr2=0;
	while (st1<=dr1 || (st1>dr1 && st2!=dr2) )
	{
		e1=Min(st1,dr1,st2,dr2);
		e2=Min(st1,dr1,st2,dr2);		
		c[++k].ap=c[e1].ap+c[e2].ap;
		c[k].fs=e1; c[k].fd=e2;
		
		sol+=c[k].ap;
		Q2[++dr2]=k;
	}	
	
	dfs(k,0,0);
	
	afisare();
	
	return 0;
}