Cod sursa(job #2620797)

Utilizator rares404AlShaytan - Balasescu Rares rares404 Data 29 mai 2020 18:03:46
Problema Coduri Huffman Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.48 kb
//
//  main.cpp
//  coduri hoofman
//
//  Created by Eusebiu Rares on 29/05/2020.
//  Copyright © 2020 Eusebiu Rares. All rights reserved.
//

#include <iostream>
#include "fstream"
#include "queue"

const int MV = 1e6 ;

std::fstream in ("huffman.in", std::ios::in) ;
std::fstream out ("huffman.out", std::ios::out) ;

class Node {
	public :
	long long left, right ;
	Node() {
		left = right = 0 ;
	}
	Node(int _left, int _right) {
		left = _left ;
		right = _right ;
	}
	bool operator == (const Node &aux) {
		return (left == aux.left and right == aux.right) ;
	}
};

long long id[MV + 1] ;
std::queue<int> firstQueue, secondQueue ;
int nodes ;
Node arb[(MV << 1) + 1] ;
Node code[(MV << 1) + 1] ;

int small() {
	if (firstQueue.empty()) {
		int candidateA = secondQueue.front() ;
		secondQueue.pop() ;
		return candidateA ;
	}
	if (secondQueue.empty()) {
		int candidateA = firstQueue.front() ;
		firstQueue.pop() ;
		return candidateA ;
	}
	int candidateA = firstQueue.front() ;
	int candidateB = secondQueue.front() ;
	if (id[candidateA] <= id[candidateB]) {
		firstQueue.pop() ;
		return candidateA ;
	} else {
		secondQueue.pop() ;
		return candidateB ;
	}
}

void addNode(int x, int y) {
	id[++ nodes] = id[x] + id[y] ;
	secondQueue.push(nodes) ;
	arb[nodes] = Node(x, y) ;
//	std::cout << nodes << "  " << x << ' ' << y << '\n' ;
}

void createArb() {
	while (firstQueue.size() + secondQueue.size() >= 2) {
		int smallest = small() ;
		int help = small() ;
//		std::cout << smallest << "   " << help << "    " << nodes + 1 << '\n' ;
		addNode(smallest, help) ;
	}
}

void dfs(int node) {
	if (node <= 0) {
		return ;
	}
	code[arb[node].left].left = code[node].left + 1 ;
	code[arb[node].right].left = code[node].left + 1 ;
	code[arb[node].left].right = code[node].right << 1 ;
	code[arb[node].right].right = (code[node].right << 1) + 1 ;
//	std::cout << arb[node].left << "  " << code[arb[node].left].left << "  " << code[arb[node].left].right << '\n' ;
	dfs(arb[node].left) ;
	dfs(arb[node].right) ;
}

int main(int argc, const char * argv[]) {
	int codes ; in >> codes ;
	for (int i = 1 ; i <= codes ; ++ i) {
		in >> id[i] ;
		firstQueue.push(i) ;
	}
	nodes = codes ;
	createArb() ;
	dfs(nodes) ;
//	for (int i = nodes ; i >= 1 ; -- i) {
//		std::cout << i << "  -> " << code[i].left << "  " << code[i].right << '\n' ;
//	}
	long long lg(0) ;
	for (int i = nodes ; i > codes ; -- i) {
		lg += id[i] ;
	}
	out << lg << '\n' ;
	for (int i = 1 ; i <= codes ; ++ i) {
		out << code[i].left << ' ' << code[i].right << '\n' ;
	}
}