Cod sursa(job #818574)

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

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;
int A_front = 1, A_back = 1, Q_front = 1, Q_back = 1;
node_t * root;
char fr[1000001];
long long sc[1000001];
node_t * A[1000001];
node_t * Q[1000001];

void dfs(node_t * root, long long code, char 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++) {
		A[i] = new node_t;
		A[i]->W = next_int();
		A[i]->i = i;
		A_back++;
	}
	while (A_back - A_front > 0 || Q_back - Q_front > 1) {
		Q[Q_back] = new node_t;
		Q[Q_back]->i = 0;
		node_t * a = 0;
		node_t * b = 0;
		if (A_back - A_front == 0) {
			a = Q[Q_front++];
		} else if (Q_back - Q_front == 0) {
			a = A[A_front++];
		} else if (A[A_front]->W <= Q[Q_front]->W) {
			a = A[A_front++];
		} else {
			a = Q[Q_front++];
		}
		if (A_back - A_front == 0) {
			b = Q[Q_front++];
		} else if (Q_back - Q_front == 0) {
			b = A[A_front++];
		} else if (A[A_front]->W <= Q[Q_front]->W) {
			b = A[A_front++];
		} else {
			b = Q[Q_front++];
		}
		Q[Q_back]->W = a->W + b->W;
		Q[Q_back]->L = a;
		Q[Q_back]->R = b;
		Q_back++;
	}
	root = Q[Q_front];
	dfs(root, 0, 0);
	printf("%lld\n", sum);
	for (int i = 1; i <= n; i++) {
		printf("%d %lld\n", int(fr[i]), sc[i]);
	}
	return 0;
}