Pagini recente » Cod sursa (job #2798070) | Cod sursa (job #672894) | Cod sursa (job #2438508) | Cod sursa (job #1976264) | Cod sursa (job #2620615)
#include <cstdio>
#include <iostream>
#include <queue>
using namespace std;
const int NMAX = 1000505;
struct node {
long long weight;
int leftChild, rightChild;
node() {}
node(long long _weight) : node(_weight, -1, -1) { }
node(long long _weight, int _leftChild, int _rightChild) {
weight = _weight;
leftChild = _leftChild;
rightChild = _rightChild;
}
};
int N, A[NMAX];
node nodes[2 * NMAX];
// first N are leaves, next N - 1 are internal nodes
int nextLeaf, nextInternalNode, totalNodes;
pair<int, long long> result[NMAX];
long long totalLength;
int extractMinimum() {
int resultIdx = -1;
if (nextLeaf == N + 1 || (nextInternalNode <= totalNodes && nodes[nextLeaf].weight > nodes[nextInternalNode].weight)) {
return nextInternalNode++;
}
return nextLeaf++;
}
void dfs(int currNodeIdx, int depth, long long currPrefix) {
if (currNodeIdx == -1) {
return;
} else if (currNodeIdx <= N) {
result[currNodeIdx] = {depth, currPrefix};
totalLength += nodes[currNodeIdx].weight * depth;
return;
}
dfs(nodes[currNodeIdx].leftChild, depth + 1, currPrefix << 1);
dfs(nodes[currNodeIdx].rightChild, depth + 1, (currPrefix << 1) + 1);
}
int main() {
freopen("huffman.in", "r", stdin);
freopen("huffman.out", "w", stdout);
cin.tie(NULL);
ios_base::sync_with_stdio(false);
cin >> N;
for (int i = 1; i <= N; i++) {
cin >> A[i];
nodes[i] = node(A[i]);
}
nextLeaf = 1;
totalNodes = N;
nextInternalNode = N + 1;
while (N + 1 - nextLeaf + (totalNodes + 1) - nextInternalNode > 1) {
int firstMin = extractMinimum();
int secondMin = extractMinimum();
int newWeight = nodes[firstMin].weight + nodes[secondMin].weight;
node newNode{newWeight, firstMin, secondMin};
nodes[++totalNodes] = newNode;
}
dfs(totalNodes, 0, 0);
cout << totalLength << "\n";
for (int i = 1; i <= N; i++) {
cout << result[i].first << " " << result[i].second << "\n";
}
return 0;
}