Cod sursa(job #1463156)

Utilizator petru.cehanCehan Petru petru.cehan Data 20 iulie 2015 13:12:54
Problema Coduri Huffman Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.73 kb
// Huffman cu doua cozi, O(n)

#include <stdio.h>

using namespace std;

const int maxn = 1000100 ;
#define inf 1LL << 60

struct nod
{
    long long frecv ;
    long fiu[2] ;
} nod[maxn << 2] ;

long long n , i, j, k, p, l[2], r[2] ;
long long q[2][maxn], lg[maxn] ;  // q - cele 2 cozi , lg - vectorul de lungimi
long long b[maxn], m, sol ;

void DFS ( long poz , long long cod , long nivel )
{
    if ( nod[poz].fiu[0] )
    {
        DFS ( nod[poz].fiu[0] , cod * 2 , nivel + 1 ) ;
        DFS ( nod[poz].fiu[1] , ( cod * 2 ) + 1 , nivel + 1 ) ;
        return;
    }
    lg[poz] = nivel ;
    b[poz] = cod ;
}

void Huffman ()
{
    k = n;
    l[0] = l[1] = 1 ;
    r[0] = n ;
    while ( l[0] + l[1] <= r[0] + r[1] )
    {
        ++ k ;
        for ( j = 0 ; j < 2 ; ++ j )
        {
            p = 0 ;
            m = inf ;
            for ( i = 0 ; i < 2 ; ++ i )
            {
                if ( nod[q[i][l[i]]].frecv < m && l[i] <= r[i] )
                {
                    p = i ;
                    m = nod[q[i][l[i]]].frecv;
                }
            }
            nod[k].fiu[j] = q[p][l[p]] ;
            nod[k].frecv += nod[q[p][l[p]]].frecv ;
            ++ l[p] ;
        }
        sol += nod[k].frecv;
        q[1][ ++ r[1] ] = k ;
    }
    DFS ( k , 0 , 0 ) ;
}

int main()
{
    freopen ( "huffman.in" , "r", stdin ) ;
    freopen ( "huffman.out" , "w", stdout ) ;
    scanf ( "%d", &n ) ;
    for ( i = 1 ; i <= n ; ++ i )
    {
        scanf ( "%d" , &nod[i].frecv );
        q[0][i] = i ;
    }
    Huffman () ;

    printf ( "%lld\n" , sol ) ;
    for ( i = 1 ; i <= n ; ++ i )
    {
        printf ( "%d %lld\n" , lg[i], b[i] ) ;
    }
    return 0;
}