Cod sursa(job #1662554)

Utilizator ArkinyStoica Alex Arkiny Data 24 martie 2016 21:01:42
Problema Coduri Huffman Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.57 kb
#include<stdio.h>
#include<queue>
using namespace std;

FILE *in, *out;

int N;

struct Node
{
	int f1, f2;
	long long val;
};

Node arb[2000010];

pair<int, long long> r[2000010];

int t = 0;
long long sol = 0;

int q[2][2000000], q1_s = 1, q1_f = 0, q2_s = 1, q2_f = 0;
int s = 0;

void DFS(int i, int 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 = fopen("huffman.in", "r");
	out = fopen("huffman.out", "w");

	fscanf(in, "%d", &N);
	for (int i = 1;i <= N;++i)
	{
		fscanf(in, "%lld", &arb[++t].val);
		q[0][++q1_f] = t;
	}

	int e1, e2, size1, size2, op,s1,aux;
	long long min;
	while (!(q1_f-q1_s+1 == 1 && q2_f<q2_s))
	{
		s1 = (s + 1) % 2;
		if (q1_f < q1_s)
			size1 = 0;
		else
			size1 = q1_f - q1_s + 1;

		if (q2_f < q2_s)
			size2 = 0;
		else
			size2 = q2_f - q2_s + 1;
		if (size2 == 0)
		{
			e1 = q[s][q1_s];
			++q1_s;
			e2 = q[s][q1_s];
			++q1_s;
		}
		else if (size1 == 1 || size2 == 1)
		{
			e1 = q[s][q1_s];
			e2 = q[s1][q2_s];
			min = arb[e1].val + arb[e2].val;
			if (size1 != 1 && size2 == 1)
			{
				if (arb[q[s][q1_s]].val + arb[q[s][q1_s+1]].val < min)
					e1 = q[s][q1_s], e2 = q[s][q1_s+1], q1_s+=2;
				else
					q1_s++,q2_s++;
			}
			else if (size1 == 1 && size2 != 1)
			{
				if (arb[q[s1][q2_s]].val + arb[q[s1][q2_s+1]].val < min)
					e1 = q[s1][q2_s], e2 = q[s1][q2_s+1], q2_s+=2;
				else
					q1_s++, q2_s++;
			}
			else
			{
				q1_s++, q2_s++;
			}
		}
		else
		{
			e1 = q[s][q1_s];
			e2 = q[s1][q2_s];
			min = arb[e1].val + arb[e2].val;
			op = 1;

			if (arb[q[s][q1_s]].val + arb[q[s][q1_s+1]].val < min)
				op = 2, min = arb[q[s][q1_s]].val + arb[q[s][q1_s+1]].val;
			if (arb[q[s1][q2_s]].val + arb[q[s1][q2_s+1]].val < min)
				op = 3;

			if (op == 1)
			{
				q1_s++, q2_s++;
			}
			else if (op == 2)
			{
				e1 = q[s][q1_s];
				e2 = q[s][q1_s+1];
				q1_s += 2;
			}
			else
			{
				e1 = q[s1][q2_s];
				e2 = q[s1][q2_s+1];
				q2_s += 2;
			}

		}

		arb[++t].f1 = e1;
		arb[t].f2 = e2;
		arb[t].val = arb[e1].val + arb[e2].val;

		q[s1][++q2_f] = t;

		if (q1_f < q1_s)
		{
			s = (s + 1) % 2;
			aux = q1_s;
			q1_s = q2_s;
			q2_s = aux;

			aux = q1_f;
			q1_f = q2_f;
			q2_f = aux;
		}
	}
	DFS(q[s][q1_s], 0, 0);
	fprintf(out, "%lld \n", sol);

	for (int i = 1;i <= N;++i)
		fprintf(out, "%d %lld \n", r[i].first, r[i].second);

	return 0;
}