Pagini recente » Cod sursa (job #34976) | Cod sursa (job #159005) | Cod sursa (job #1056844) | Cod sursa (job #1693312) | Cod sursa (job #1662058)
#include<fstream>
#include<queue>
using namespace std;
ifstream in("huffman.in");
ofstream out("huffman.out");
int N;
struct Node
{
int f1, f2;
long long val;
};
Node arb[3000010];
pair<int,long long> r[1000010];
int t = 0;
long long sol=0;
deque<int> q[2];
int s = 0;
void DFS(int i,long long nr,long long e)
{
if (arb[i].f1 != 0)
{
DFS(arb[i].f1,nr+1,e<<1);
DFS(arb[i].f2,nr+1,(e<<1)|1LL);
}
else
{
r[i]=make_pair(nr, e);
sol += nr*arb[i].val;
}
}
int main()
{
in >> N;
for (int i = 1;i <= N;++i)
{
int e;
in >> e;
arb[++t].f1 = 0, arb[t].f2 = 0,arb[t].val=e;
q[0].push_back(t);
}
int e1, e2,size1,size2,min,op;
while (!(q[s].size()==1 && q[(s+1)%2].size()==0))
{
size2 = q[(s + 1) % 2].size();
size1 = q[s].size();
if (size2 == 0)
{
e1 = q[s].front();
q[s].pop_front();
e2 = q[s].front();
q[s].pop_front();
}
else if (size2 == 1 || size1 == 1)
{
e1 = q[s][0];
e2 = q[(s + 1) % 2][0];
min = arb[e1].val + arb[e2].val;
if(size2==1 && size1!=1)
{
if (arb[q[s][0]].val + arb[q[s][1]].val < min)
e1 = q[s][0], e2 = q[s][1], q[s].pop_front(), q[s].pop_front();
else
q[s].pop_front(), q[(s + 1) % 2].pop_front();
}
else if(size1==1 && size2!=1)
{
if (arb[q[(s + 1) % 2][0]].val + arb[q[(s + 1) % 2][1]].val < min)
e1 = q[(s + 1) % 2][0], e2 = q[(s + 1) % 2][1], q[(s + 1) % 2].pop_front(), q[(s + 1) % 2].pop_front();
else
q[s].pop_front(), q[(s + 1) % 2].pop_front();
}
else
{
q[s].pop_front();
q[(s + 1) % 2].pop_front();
}
}
else
{
e1 = q[s][0];
e2 = q[(s + 1) % 2][0];
min = arb[e1].val + arb[e2].val;
op = 1;
if (arb[q[s][0]].val + arb[q[s][1]].val < min)
op = 2, min = arb[q[s][0]].val + arb[q[s][1]].val;
if (arb[q[(s + 1) % 2][0]].val + arb[q[(s + 1) % 2][1]].val < min)
op = 3;
if (op == 1)
{
q[s].pop_front();
q[(s + 1) % 2].pop_front();
}
else if (op == 2)
{
e1 = q[s][0];
e2 = q[s][1];
q[s].pop_front();
q[s].pop_front();
}
else
{
e1 = q[(s+1)%2][0];
e2 = q[(s + 1) % 2][1];
q[(s + 1) % 2].pop_front();
q[(s + 1) % 2].pop_front();
}
}
arb[++t].f1 = e1;
arb[t].f2 = e2;
arb[t].val = arb[e1].val + arb[e2].val;
q[(s + 1) % 2].push_back(t);
if (q[s].size() == 0)
s = (s + 1) % 2;
}
DFS(q[s].front(), 0, 0);
out << sol<<'\n';
for (int i = 1;i <= N;++i)
out << r[i].first << " " << r[i].second << '\n';
return 0;
}