Cod sursa(job #904147)

Utilizator Cosmin1490Balan Radu Cosmin Cosmin1490 Data 3 martie 2013 19:52:11
Problema Coduri Huffman Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 2.46 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];

int l[NMAX];

long long lg;
long long bi[NMAX];


struct HNod
{

	long long sum;
	int i;
	HNod *s;
	HNod *d;
	
	HNod(long long 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((1LL<<60), -1);

queue<HNod*> q[2];

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

	char buffer[6 * 1024];

	int i = -1 ;
	int currentNumber = 0;
	while(fin.good())
	{
		
		
		fin.read(buffer, 6 * 1024);
		int count = fin.gcount();


		for(int j = 0; j < count; j++)
		{
			
			if (isdigit(buffer[j]) != 0)
			{
				currentNumber *= 10;
				currentNumber += buffer[j] - '0';
			}
			else
			{
				if(i == -1)
				{
					N = currentNumber;
					currentNumber = 0;
					i++;
				}
				else
				{	
					
					A[i] = currentNumber;
					q[0].push(new HNod(A[i], i));
					i++;
					currentNumber = 0;
				}
				
			}
		}
	}
	if(currentNumber != 0)
	{
		A[i] = currentNumber;
		q[0].push(new HNod(A[i], i));
		i++;
	}

	fin.close();
}




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()
{


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

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

}