Cod sursa(job #600124)

Utilizator ChallengeMurtaza Alexandru Challenge Data 30 iunie 2011 16:47:56
Problema Coduri Huffman Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.54 kb
#include <fstream>
#include <queue>

using namespace std;

const char InFile[]="huffman.in";
const char OutFile[]="huffman.out";
const int MaxN=1000111;

ifstream fin(InFile);
ofstream fout(OutFile);

struct nod
{
	nod(nod *left=NULL, nod *right=NULL, long long w=0, int pos=0):left(left),right(right),w(w),pos(pos){}
	nod *left,*right;
	long long w;
	int pos;
};

struct el
{
	el(long long cod=0, int l=0):cod(cod),l(l){}
	long long cod;
	int l;
};

int N,x;
queue<nod*> q1,q2;
el v[MaxN];

inline nod* getmin()
{
	nod *sol=NULL;
	if(!q1.empty())
	{
		sol=q1.front();
	}
	if(!q2.empty())
	{
		if(sol)
		{
			if(sol->w>q2.front()->w)
			{
				sol=q2.front();
			}
		}
		else
		{
			sol=q2.front();
		}
	}
	if(!q1.empty())
	{
		if(sol==q1.front())
		{
			q1.pop();
		}
		else
		{
			q2.pop();
		}
	}
	else
	{
		q2.pop();
	}
	return sol;
}

long long dfs(nod *n, long long cod, int l)
{
	if(n->left!=NULL && n->right!=NULL)
	{
		return dfs(n->left,cod<<1,l+1)+dfs(n->right,(cod<<1)+1,l+1)+n->w;
	}
	else
	{
		v[n->pos].cod=cod;
		v[n->pos].l=l;
		return 0;
	}
}

int main()
{
	fin>>N;
	for(register int i=1;i<=N;++i)
	{
		fin>>x;
		q1.push(new nod(NULL,NULL,x,i));
	}
	fin.close();

	while(q1.size()+q2.size()>=2)
	{
		nod *left=getmin();
		nod *right=getmin();
		q2.push(new nod(left,right,left->w+right->w));
	}
	nod *root=getmin();

	fout<<dfs(root,0,0)<<"\n";
	for(register int i=1;i<=N;++i)
	{
		fout<<v[i].l<<" "<<v[i].cod<<"\n";
	}
	fout.close();
	return 0;
}