Cod sursa(job #1321334)

Utilizator cernat.catallinFMI Cernat Catalin Stefan cernat.catallin Data 19 ianuarie 2015 00:10:28
Problema Coduri Huffman Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.04 kb
#include <queue>
#include <fstream>
#include <iostream>
using namespace std;

ifstream in("huffman.in");
ofstream out("huffman.out");

typedef long long int int64;

const int max_size = 1000005;

struct TreeNode {
	int64 frequency;
	int64 code;
	int length;
	int left_son, right_son;

	TreeNode() : frequency(0), code(0), left_son(0), right_son(0),
		length(0) {}
};

struct symbol {
	int frequency;
	int64 position_tree;

	symbol() : frequency(0), position_tree(0) {}

	symbol(int64 frequency, int position_tree) :
		frequency(frequency), position_tree(position_tree) {}

	bool operator < (symbol &rhs) const {
		return frequency < rhs.frequency;
	}
};

int n;
int64 total_length;
TreeNode tree[2 * max_size];
queue<symbol> queue1, queue2;

symbol ExtractMin() {
	symbol result;

	if (queue1.empty()) {
		result = queue2.front();
		queue2.pop();
	}
	else if (queue2.empty()) {
		result = queue1.front();
		queue1.pop();
	}
	else if (queue1.front() < queue2.front()) {
		result = queue1.front();
		queue1.pop();
	}
	else {
		result = queue2.front();
		queue2.pop();
	}

	return result;
}

void AssignCodes(int node, int64 code, int length) {
	if (tree[node].left_son) {
		AssignCodes(tree[node].left_son, code << 1, length + 1);
		AssignCodes(tree[node].right_son, (code << 1) + 1, length + 1);
		return;
	}
	tree[node].code = code;
	tree[node].length = length;
	total_length += (tree[node].length * tree[node].frequency);
}

int main() {
	in >> n;

	for (int i = 1; i <= n; ++i) {
		in >> tree[i].frequency;
		queue1.push(symbol(tree[i].frequency, i));
	}

	for (int i = n + 1; i < 2 * n; ++i) {
		symbol x = ExtractMin();
		symbol y = ExtractMin();

		tree[i].frequency = x.frequency + y.frequency;
		tree[i].left_son = y.position_tree;
		tree[i].right_son = x.position_tree;
		queue2.push(symbol(tree[i].frequency, i));
	}
	AssignCodes(2 * n - 1, 0, 0);

	out << total_length << '\n';
	for (int i = 1; i <= n; ++i)
		out << tree[i].length << ' ' << tree[i].code << '\n';

	return 0;
}