Cod sursa(job #1222532)

Utilizator Luncasu_VictorVictor Luncasu Luncasu_Victor Data 23 august 2014 15:28:24
Problema Coduri Huffman Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.61 kb
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
#define MAX 1000010

int N, Freq[3*MAX], Left[3*MAX], Right[3*MAX], Len[MAX];
long long Sol, Codes[MAX];
queue<int> Q1, Q2;

void Huffman() {
	int X, Y, Z = N;
	while (Q1.size() + Q2.size() > 1) {
		if (Q1.size() == 0) {
			X = Q2.front();
			Q2.pop();
		} else
		if (Q2.size() == 0) {
			X = Q1.front();
			Q1.pop();
		} else {
			if (Freq[Q1.front()] < Freq[Q2.front()]) {
				X = Q1.front();
				Q1.pop();
			} else {
				X = Q2.front();
				Q2.pop();
			}
		}
		if (Q1.size() == 0) {
			Y = Q2.front();
			Q2.pop();
		} else
		if (Q2.size() == 0) {
			Y = Q1.front();
			Q1.pop();
		} else {
			if (Freq[Q1.front()] < Freq[Q2.front()]) {
				Y = Q1.front();
				Q1.pop();
			} else {
				Y = Q2.front();
				Q2.pop();
			}
		}
		++Z;
		Freq[Z] = Freq[X] + Freq[Y];
		Left[Z] = X;
		Right[Z] = Y;
		Q1.push(Z);
	}
}

void DFS(int X, int L, long long Code) {
	if (Left[X] == 0 && Right[X] == 0) {
		Len[X] = L;
		Codes[X] = Code;
		Sol += Freq[X] * L;
	} else {
		DFS(Left[X], L+1, (Code<<1));
		DFS(Right[X], L+1, (Code<<1) + 1);
	}
}

int main() {

	freopen("huffman.in","r",stdin);
	freopen("huffman.out","w",stdout);
	scanf("%d", &N);

	for (int i = 1; i <= N; i++) {
		scanf("%d", &Freq[i]);
		Q2.push(i);
	}
	
	Huffman();
	DFS(Q1.front(), 0, 0);

	printf("%lld\n", Sol);
	for (int i = 1; i <= N; i++) {
		printf("%d %lld\n", Len[i], Codes[i]);
	}
	
	return 0;
}