Cod sursa(job #904165)

Utilizator Cosmin1490Balan Radu Cosmin Cosmin1490 Data 3 martie 2013 20:19:26
Problema Coduri Huffman Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 2.32 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 1000002

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;
int cursor = 0;
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;
					i++;
					currentNumber = 0;
				}
				
			}
		}
	}
	if(currentNumber != 0)
	{
		A[i] = currentNumber;
		i++;
	}

	fin.close();
}


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

	if(cursor < N && A[cursor] < (q.empty() ? NIL->sum : q.front()->sum))
	{
		min = new HNod(A[cursor], cursor);
		cursor++;
	}
	else
	{
		min = q.front();
		q.pop();
	}
	
	return min;

}



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


void solve()
{


	while(cursor != N || q.empty() == false)
	{
		HNod* min1 = extractMin();
		HNod* min2 = extractMin();

		q.push(new HNod(min1, min2));

		if(cursor == N && q.size() == 1)
			break;
	}

	dfs(0, q.front(), 0);

}






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

}