Pagini recente » Cod sursa (job #2728290) | Cod sursa (job #3261815) | Cod sursa (job #849599) | Cod sursa (job #1721965) | Cod sursa (job #2251534)
#include <fstream>
#include <queue>
#include <cstdio>
struct Node { long long val; long leftPos, rightPos;};
Node nodes[2000001];
long long len[1000001];
long long code[1000001];
int getNodePosWithMinValue(Node nodes[], std::queue<long>& initial, std::queue<long>& internal)
{
long pos = -1;
if(initial.empty())
{
pos = internal.front();
internal.pop();
}
else if(internal.empty())
{
pos = initial.front();
initial.pop();
}
else
{
long initialFront = initial.front();
long internalFront = internal.front();
if(nodes[initialFront].val < nodes[internalFront].val)
{
pos = initialFront;
initial.pop();
}
else
{
pos = internalFront;
internal.pop();
}
}
return pos;
}
long Huffman(Node nodes[], long n, std::queue<long> initial)
{
std::queue<long> internal;
while( ( initial.size() + internal.size() ) > 1)
{
long leftPos = getNodePosWithMinValue(nodes, initial, internal);
long rightPos = getNodePosWithMinValue(nodes, initial, internal);
nodes[++n].val = nodes[leftPos].val + nodes[rightPos].val;
nodes[n].leftPos = leftPos;
nodes[n].rightPos = rightPos;
internal.push(n);
}
return internal.front();
}
void DepthFirst(Node nodes[], long pos, long long val = 0, long length = 0)
{
if (nodes[pos].leftPos != -1)
{
DepthFirst(nodes, nodes[pos].leftPos, val * 2, length + 1);
}
if (nodes[pos].rightPos != -1)
{
DepthFirst(nodes, nodes[pos].rightPos, val * 2 + 1, length + 1);
}
if (nodes[pos].rightPos == -1 && nodes[pos].leftPos == -1)
{
len[pos] = length;
code[pos] = val;
}
}
int main()
{
freopen("huffman.in", "r", stdin);
freopen("huffman.out", "w", stdout);
long n;
scanf("%ld", &n);
std::queue<long> initial;
for(long i = 0; i < n; ++i)
{
scanf("%lld", &nodes[i].val);
nodes[i].leftPos = -1;
nodes[i].rightPos = -1;
initial.push(i);
}
long root = Huffman(nodes, n, initial);
DepthFirst(nodes, root);
long long lg = 0;
for (long i = 0; i < n; ++i)
{
lg += len[i] * nodes[i].val;
}
printf("%lld\n", lg);
for (long i = 0; i < n; ++i)
{
printf("%lld %lld\n", len[i], code[i]);
}
return 0;
}