Cod sursa(job #1662058)

Utilizator ArkinyStoica Alex Arkiny Data 24 martie 2016 14:12:20
Problema Coduri Huffman Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 2.57 kb
#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;
}