Cod sursa(job #818552)

Utilizator ahmed.abdraboahmed.abdrabo ahmed.abdrabo Data 17 noiembrie 2012 17:09:50
Problema Coduri Huffman Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 1.76 kb
#include <cstdio>
#include <deque>
#include <cassert>
#include <vector>

using namespace std;

inline int next_int() {
	int n = 0;
	char c = getchar_unlocked();
	while (!('0' <= c && c <= '9')) {
		c = getchar_unlocked();
	}
	while ('0' <= c && c <= '9') {
		n = n * 10 + c - '0';
		c = getchar_unlocked();
	}
	return n;
}

struct node_t {
	long long W;
	int i;
	node_t * L;
	node_t * R;
};

long long n, sum;
deque<node_t*> A, Q;
node_t * root;
int fr[1000001];
long long sc[1000001];

void dfs(node_t * root, long long code, int depth) {
	if (root == 0)
		return;
	if (root->i == 0) {
		sum += root->W;
		dfs(root->L, code << 1, depth + 1);
		dfs(root->R, code << 1 | 1, depth + 1);
	} else {
		fr[root->i] = depth;
		sc[root->i] = code;
	}
}

int main() {
	freopen("huffman.in", "r", stdin);
	freopen("huffman.out", "w", stdout);
	n = next_int();
	for (int i = 1; i <= n; i++) {
		node_t * a = new node_t;
		a->W = next_int();
		a->i = i;
		A.push_back(a);
	}
	while (A.size() > 0 || Q.size() > 1) {
		node_t * p = new node_t;
		p->i = 0;
		node_t * a = 0;
		node_t * b = 0;
		if (A.size() == 0) {
			a = Q.front();
			Q.pop_front();
		} else if (Q.size() == 0) {
			a = A.front();
			A.pop_front();
		} else if (A.front()->W <= Q.front()->W) {
			a = A.front();
			A.pop_front();
		} else {
			a = Q.front();
			Q.pop_front();
		}
		if (A.size() == 0) {
			b = Q.front();
			Q.pop_front();
		} else if (Q.size() == 0) {
			b = A.front();
			A.pop_front();
		} else if (A.front()->W <= Q.front()->W) {
			b = A.front();
			A.pop_front();
		} else {
			b = Q.front();
			Q.pop_front();
		}
		p->W = a->W + b->W;
		p->L = a;
		p->R = b;
		Q.push_back(p);
	}
	root = Q.front();
	dfs(root, 0, 0);
	printf("%lld\n", sum);
	for (int i = 1; i <= n; i++) {
		printf("%d %lld\n", fr[i], sc[i]);
	}
	return 0;
}