Cod sursa(job #904097)

Utilizator Cosmin1490Balan Radu Cosmin Cosmin1490 Data 3 martie 2013 18:50:23
Problema Coduri Huffman Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 1.93 kb
#include <fstream>
#include <iostream>
#include <string>
#include <queue>
#include <vector>

using namespace std;


const string file = "huffman";

const string infile = file + ".in";
const string outfile = file + ".out";


#define NMAX 1000000

int N;
int A[NMAX];

long l[NMAX];

long long lg;
long long bi[NMAX];


void citire()
{
	fstream fin(infile.c_str(), ios::in);

	fin >> N;

	for(int i = 0; i < N; i++)
	{
		fin >> A[i];
	}
	fin.close();
}



struct HNod
{

	int sum;
	int i;
	HNod *s;
	HNod *d;
	
	HNod(int sum, int i)
	{
		this->i = i;
		this->sum = sum;
	}

	HNod(HNod* s, HNod* d)
	{
		this->i = -1;
		this->s = s;
		this->d = d;
		this->sum = s->sum + d->sum;
	}

};


HNod* NIL = new HNod(1<<30, -1);

queue<HNod*> q[2];


HNod* extractMin()
{
	HNod* min = 0;

	HNod* min1 = q[0].empty() ? NIL : q[0].front();
	HNod* min2 = q[1].empty() ? NIL : q[1].front();


	if(min1->sum < min2->sum)
	{
		min = min1;
		q[0].pop();
	}
	else
	{
		min = min2;
		q[1].pop();
	}

	return min;

}



void dfs(int nivel, HNod* nod, long long b)
{
	if(nod->i != -1)
	{
		l[nod->i] = nivel;
		bi[nod->i] = b;
	}
	else
	{
		dfs(nivel + 1, nod->s, b << 1 );
		dfs(nivel + 1, nod->d, (b << 1) + 1);
	}
}


void solve()
{
	for(int i = 0; i < N; i++)
	{
		q[0].push(new HNod(A[i], i));
	}

	while(q[0].empty() == false || q[1].empty()==false)
	{
		HNod* min1 = extractMin();
		HNod* min2 = extractMin();

		q[1].push(new HNod(min1, min2));

		if(q[0].empty() && q[1].size() == 1)
			break;
	}



	dfs(0, q[1].front(), 0);

	lg = 0;

	for(int i = 0; i < N; i++)
	{
		lg += A[i] * l[i];
	}

}






void afisare()
{
	fstream fout(outfile.c_str(), ios::out);

	fout << lg << "\n";

	for(int i = 0; i < N; i++)
	{
		fout << l[i] << " " << bi[i] << "\n";
	}

	fout.close();
}

int main()
{
	citire();
	solve();
	afisare();

}