Cod sursa(job #1321337)

Utilizator cernat.catallinFMI Cernat Catalin Stefan cernat.catallin Data 19 ianuarie 2015 00:21:47
Problema Coduri Huffman Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.38 kb
//#include <fstream>
//#include <iostream>
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <queue>
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;
	int left_son, right_son;

	TreeNode() : frequency(0), left_son(0), right_son(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;
	}

	/*
		Have to use frequency for code and left_son for length to stay in
		memory limits.
	*/
	total_length += (length * tree[node].frequency);
	tree[node].frequency = code;
	tree[node].left_son = length;
}

int main() {
	freopen("huffman.in", "r", stdin);
	freopen("huffman.out", "w", stdout);
	//in >> n;
	scanf("%d", &n);

	for (int i = 1; i <= n; ++i) {
		//in >> tree[i].frequency;
		scanf("%lld", &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';
	printf("%lld\n", total_length);
	for (int i = 1; i <= n; ++i)
		//out << tree[i].left_son << ' ' << tree[i].frequency << '\n';
		printf("%d %lld\n", tree[i].left_son, tree[i].frequency);

	return 0;
}