Cod sursa(job #383751)

Utilizator GotenAmza Catalin Goten Data 17 ianuarie 2010 22:21:39
Problema Coduri Huffman Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.91 kb
#include<fstream.h>
#include<iostream.h>

int k,n,i,a[1000100],lim,p1,p2,u1,u2,c[1000100],j,niv[2000100],h[1000100],lg;
long long w[2000100][3],b[2000100];


void dfsn(int nod, int nivel)
{
	niv[nod]=nivel;
	if(w[nod][1])
	{
		dfsn(w[nod][1],nivel+1);
		dfsn(w[nod][2],nivel+1);
	}
}
	
void dfsb(int nod, int bob, int key, int nivel)
{
	if(!w[nod][1]&&niv[nod]==key)
		b[nod]=bob;
	if(w[nod][1])
	{
		dfsb(w[nod][1],bob+(1<<(key-1-nivel)),key,nivel+1);
		dfsb(w[nod][2],bob,key,nivel+1);
	}
}

int main()
{
	ifstream f("huffman.in");
	ofstream g("huffman.out");
	f>>n;
	for(i=1;i<=n;i++)
		f>>a[i];
	k=0;
	lim=2*n-1;
	p1=1;
	u1=n;
	p2=1;
	u2=0;
	while(k<lim)
	{
		if(a[p1+1]&&(a[p1+1]<=w[c[p2]][0]||p2>u2))
		{
			w[++k][0]=a[p1];
			h[p1]=k;
			w[k][1]=0;
			w[k][2]=0;
			w[++k][0]=a[p1+1];
			h[p1+1]=k;
			w[k][1]=0;
			w[k][2]=0;
			w[++k][0]=a[p1]+a[p1+1];
			c[++u2]=k;
			w[k][1]=k-1;
			w[k][2]=k-2;
			p1+=2;
		}
		else
			if(w[c[p2+1]][0]&&(w[c[p2+1]][0]<=a[p1]||p1>u1))
			{
				w[++k][0]=w[c[p2]][0]+w[c[p2+1]][0];
				c[++u2]=k;
				w[k][1]=c[p2+1];
				w[k][2]=c[p2];
				p2+=2;
			}
			else 
				if(p1<=u1&&p2<=u2&&w[c[p2]][0]<=a[p1]&&(a[p1]<=w[c[p2+1]][0]||p2==u2))
				{
					w[++k][0]=a[p1];
					h[p1]=k;
					w[k][1]=0;
					w[k][2]=0;
					w[++k][0]=a[p1]+w[c[p2]][0];
					c[++u2]=k;
					w[k][1]=k-1;
					w[k][2]=c[p2];
					p1++;
					p2++;
				}
				else
					if(p1<=u1&&p2<=u2&&a[p1]<=w[c[p2]][0]&&(w[c[p2]][0]<=a[p1+1]||p1==u1))
					{
						w[++k][0]=a[p1];
						h[p1]=k;
						w[k][1]=0;
						w[k][2]=0;
						w[++k][0]=a[p1]+w[c[p2]][0];
						c[++u2]=k;
						w[k][1]=c[p2];
						w[k][2]=k-1;
						p1++;
						p2++;
					}
	}
	dfsn(lim,0);
	for(i=niv[h[n]];i<=niv[h[1]];i++)
		dfsb(lim,0,i,0);		
	for(i=1;i<lim;i++)
		lg+=w[i][0];
	g<<lg<<'\n';
	for(i=1;i<=n;i++)
		g<<niv[h[i]]<<' '<<b[h[i]]<<'\n';
	return 0;
}