Cod sursa(job #1468129)

Utilizator al.mocanuAlexandru Mocanu al.mocanu Data 5 august 2015 11:57:03
Problema Coduri Huffman Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.84 kb
#include <stdio.h>
#include <queue>
#define MAX 1000005
using namespace std;

typedef struct{
	int v, l, r, p;
} node;

queue<node> qni, qne;
node arb[2 * MAX];
int n, i, x, poz;
long long lg;

node createnode(node a, node b, int poz);
void huffman();
void dfs(node n, int code, int level);

int main(){
	freopen("huffman.in", "r", stdin);
	freopen("huffman.out", "w", stdout);
	scanf("%d", &n);
	for(i = 0; i < n; i++){
		scanf("%d", &x);
		arb[i].v = x;
		arb[i].l = arb[i].r = -1;
		arb[i].p = i;
		qne.push(arb[i]);
	}

	poz = n;
	huffman();
	printf("%lld\n", lg);
	dfs(arb[poz - 1], 0, 0);
	return 0;
}

node createnode(node a, node b, int poz){
	node x;
	x.v = a.v + b.v;
	x.l = a.p;
	x.r = b.p;
	x.p = poz;

	return x;
}

void huffman(){
	while(!qni.empty() || !qne.empty()){
		node a, b;
		if(qni.empty()){
			a = qne.front(); qne.pop();
			b = qne.front(); qne.pop();
			arb[poz] = createnode(a, b, poz); qni.push(arb[poz]);
			lg += arb[poz++].v;
		}

		else{
			if(qne.empty()){
				a = qni.front(); qni.pop();
				if(qni.empty())
					return;
				else{
					b = qni.front(); qni.pop();
					arb[poz] = createnode(a, b, poz); qni.push(arb[poz]);
					lg += arb[poz++].v;
				}
			}
			
			else{
				if(qne.front().v < qni.front().v){
					a = qne.front(); qne.pop();
				}
				else{
					a = qni.front(); qni.pop();
				}

				if(qne.empty()){
					b = qni.front(); qni.pop();
				}
				else if(qni.empty()){
					b = qne.front(); qne.pop();
				}
				else{
					if(qne.front().v < qni.front().v){
						b = qne.front(); qne.pop();
					}
					else{
						b = qni.front(); qni.pop();
					}
				}

				arb[poz] = createnode(a, b, poz); qni.push(arb[poz]);
				lg += arb[poz++].v;
			}
		}
	}
}

void dfs(node n, int code, int level){
	if(n.l == -1){
		printf("%d %d\n", level, code);
		return;
	}

	dfs(arb[n.l], 2 * code, level + 1);
	dfs(arb[n.r], 2 * code + 1, level + 1);
}