Cod sursa(job #2276943)

Utilizator cezar.plescaCezar Plesca cezar.plesca Data 5 noiembrie 2018 17:12:06
Problema Coduri Huffman Scor 65
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.16 kb
#include<stdio.h>
#include<stdlib.h>

#include<vector>
#include<queue>
#include<set>

using namespace std;

#define NMAX 1000000

int* v;
long long * b;
unsigned char * lb;

long long lung;

typedef struct nod{
	int parent, left, right;
	long long freq; 
}nod; 

vector<nod> huff; // arborele Huffman

struct pair_compare {
    bool operator() (const std::pair<long long,int> & p1, const std::pair<long long,int> & p2) const {
		if(p1.first == p2.first)
			return (p1.second < p2.second);
		else
			return (p1.first < p2.first);
    }
};

set<pair<long long,int>,pair_compare> freq; // first freq, second node

int N;

void huffman(){
	int n=N; 
	set<pair<long long,int>,pair_compare>::iterator it;
	int i,j;
	long long fi,fj;

	while(n<(2*N-1)){ 
		it=freq.begin(); 
		i=it->second; fi=it->first;
		freq.erase(it);
		it=freq.begin(); 
		j=it->second; fj=it->first;
		freq.erase(it);
		
		freq.insert(make_pair(fi+fj,n));

		huff[i].freq=fi; huff[j].freq=fj;

		huff[n].freq=fi+fj;
		huff[n].left=i; huff[n].right=j;
		huff[i].parent=n; huff[j].parent=n;
		
		n++;
	}
}

void buildDictionary(){
	int node, parent;
	//lb=0, b=0;
	for(int i=0;i<N;i++){
	    node=i;
	    while(node!=(2*N-2)){ // 254 este radacina!
	        parent=huff[node].parent;
	        if(huff[parent].left==node)
				lb[i]++;
	        else{
				b[i]+=(1LL<<lb[i]);
				lb[i]++;
	        }
	        node=parent; 
	    }
		//printf("%d %lld\n",lb[i],b[i]);
	}
}


int main(){
	freopen("huffman.in","rt",stdin);
	freopen("huffman.out","wt",stdout);
	
	scanf("%d",&N);
	huff.reserve(2*N-1);

	//int f;
	v = new int[N];
	b = (long long *)calloc(N, sizeof(long long));
	lb = (unsigned char *)calloc(N, sizeof(unsigned char));

	for(int i=0;i<N;i++){
		scanf("%d",&v[i]);
		freq.insert(make_pair(v[i],i));
	}

	// initializare arbore
	nod Node={-1,-1,-1,0};
	for(int i=0;i<(2*N-1);i++){
		huff.push_back(Node);
	}

	huffman();
	buildDictionary();

	for(int i=0;i<N;i++)
		lung+=lb[i]*huff[i].freq;

	printf("%lld\n",lung);
	
	for(int i=0;i<N;i++)
		printf("%d %lld\n",lb[i],b[i]);

	delete v;
	free(lb);
	free(b);

	return 0;
}