Cod sursa(job #1715246)

Utilizator Cristian1997Vintur Cristian Cristian1997 Data 10 iunie 2016 10:35:11
Problema Coduri Huffman Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.12 kb
using namespace std;
#include <fstream>
#include <vector>
#include <algorithm>
#include <string>
#include <queue>
using ll = long long;
using uint = unsigned int;
using ull = unsigned long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
#define Nmax 

struct _node { int ord; ll freq; _node *l, *r; };
class _queue
{
private:
	queue< _node* > Q1, Q2;

public:
	void init(const vector< int > &v)
	{
		for (int i = 0; i < static_cast<int>(v.size()); ++i)
		{
			_node *temp = new _node;
			temp->l = temp->r = nullptr;
			temp->freq = v[i];
			temp->ord = i;

			Q1.push(temp);
		}
	}

	_node* getMin()
	{
		_node *ret;

		if (Q1.empty()) ret = Q2.front(), Q2.pop();
		else if (Q2.empty()) ret = Q1.front(), Q1.pop();
		else if (Q1.front()->freq < Q2.front()->freq)
		{
			ret = Q1.front();
			Q1.pop();
		}
		else
		{
			ret = Q2.front();
			Q2.pop();
		}

		return ret;
	}

	void push(_node *node)
	{
		Q2.push(node);
	}

	int size()
	{
		return static_cast<int>(Q1.size() + Q2.size());
	}
} Q;

int n;
vector< int > freq, lg;
vector< ll > codes;

void read();
void getCodes(_node*, ll, int);
void write();

int main()
{
	_node *root;

	read();

	Q.init(freq);
	while (Q.size() > 1)
	{
		root = new _node;
		root->l = Q.getMin();
		root->r = Q.getMin();
		root->freq = root->l->freq + root->r->freq;
		root->ord = -1;

		Q.push(root);
	}

	codes.resize(n);
	lg.resize(n);

	getCodes(root, 0, 0);

	write();

    return 0;
}


void read()
{
	ifstream fin("huffman.in");

	fin >> n;
	freq.resize(n);

	for (int i = 0; i < n; ++i) fin >> freq[i];

	fin.close();
}

void getCodes(_node* node, ll code, int l)
{
	if (!node->l) codes[node->ord] = code, lg[node->ord] = l;
	else
	{
		getCodes(node->l, code << 1, l + 1);
		getCodes(node->r, (code << 1) + 1, l + 1);
	}
}

void write()
{
	int i;
	ll lgCode;
	ofstream fout("huffman.out");

	for (lgCode = 0, i = 0; i < n; ++i)
		lgCode += 1LL * freq[i] * lg[i];

	fout << lgCode << '\n';

	for (i = 0; i < n; ++i)
		fout << lg[i] << ' ' << codes[i] << '\n';

	fout.close();
}