Cod sursa(job #608056)

Utilizator vlad.maneaVlad Manea vlad.manea Data 14 august 2011 19:56:54
Problema Coduri Huffman Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.23 kb
#include <cstdio>
#include <vector>
#include <limits>
#include <algorithm>

using namespace std;

#define INFILE "huffman.in"
#define OUTFILE "huffman.out"

int N;
vector<long long> V;
vector<int> L, R;
const long long INF = numeric_limits<long long>::max();

void read()
{
	long long v;
	int i;
	freopen(INFILE, "r", stdin);
	scanf("%d", &N);
	
	for (int node = 0; node < N; ++node)
	{
		scanf("%lld", &v);		
		V.push_back(v);
		L.push_back(-1);
		R.push_back(-1);
	}
}

bool compare(const pair<long long, int> &firstPair, const pair<long long, int> &secondPair)
{
	return firstPair.first < secondPair.first || firstPair.first == secondPair.first && firstPair.second < secondPair.second;
}

long long getInnerSum()
{
	long long sum = 0;

	for (int node = N; node < V.size(); ++node)
		sum += V[node];

	return sum;
}

void solve()
{
	int index, jndex, kndex, M;
	pair<long long, int> W[4];

	for (index = 0, jndex = N, M = N * 2 - 1, kndex = N; kndex < M; ++kndex)
	{
		// pun cei patru candidati
		W[0] = make_pair((index < N - 1?			V[index + 1]:	INF),	index + 1);
		W[1] = make_pair((index < N?				V[index]:		INF),	index);
		W[2] = make_pair((jndex < V.size() - 1?		V[jndex + 1]:	INF),	jndex + 1);
		W[3] = make_pair((jndex < V.size()?			V[jndex]:		INF),	jndex);
		
		// sortez sirul de candidati
		sort(W, W + 4, compare);

		// fac modificarile necesare
		V.push_back(W[0].first + W[1].first);
		L.push_back(W[0].second);
		R.push_back(W[1].second);

		// incrementez valorile
		if (W[0].second == index)
		{
			if (W[1].second == index + 1) 
				++index;
			else 
				++jndex;

			++index;
		}
		else
		{
			if (W[1].second == jndex + 1)
				++jndex;
			else
				++index;

			++jndex;
		}
	}
}

void traverse(long long sum, int node, int length)
{
	if (node < N)
	{
		V[node] = sum;
		L[node] = length;
		return;
	}

	traverse(sum << 1, L[node], length + 1);
	traverse(sum << 1 | 1, R[node], length + 1);
}

void write()
{
	freopen(OUTFILE, "w", stdout);
	printf("%lld\n", getInnerSum());
	traverse(0LL, V.size() - 1, 0);
	for (int node = 0; node < N; ++node)
		printf("%d %lld\n", L[node], V[node]);
}

int main()
{
	read();
	solve();
	write();
	return 0;
}