Cod sursa(job #2716612)

Utilizator ionanghelinaIonut Anghelina ionanghelina Data 5 martie 2021 13:23:57
Problema Coduri Huffman Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.52 kb
#include<bits/stdc++.h>
using namespace std;

deque<pair<int,int> > q,q2;
vector<pair<int,pair<int,long long> > > sol;

const int maxN=(2e6)+5;

bool cmp(pair<int,pair<int,int> > a,pair<int,pair<int,int> > b)
{
    return a.second.second<=b.second.second;
}

vector<int> g[maxN];

int frecv[maxN];

void dfs(int node,int len,long long code)
{
    if(g[node].empty())
    {
        sol.push_back(make_pair(node,make_pair(len,code)));
        return;
    }
    dfs(g[node][0],len+1,code*2LL);
    dfs(g[node][1],len+1,code*2LL+1LL);

}
int main()
{
    freopen("huffman.in","r",stdin);
    freopen("huffman.out","w",stdout);


    int n;

    scanf("%d",&n);


    for(int i=1;i<=n;i++)
    {
        int x;
        scanf("%d",&x);
        frecv[i]=x;
        q.push_back(make_pair(i,x));
    }


    int currentNode=n;

    while(1)
    {
        vector<pair<int,pair<int,int> >> vect; //for the current Minimum

        int cnt=0;

        while(!q.empty() && cnt<2)
        {
            vect.push_back(make_pair(1,q.front()));
            q.pop_front();
            cnt++;
        }

        cnt=0;


        while(!q2.empty() && cnt<2)
        {
            vect.push_back(make_pair(2,q2.front()));
            q2.pop_front();
            cnt++;
        }

        reverse(vect.begin(),vect.end());

        for(auto it:vect)
            if(it.first==1) q.push_front(it.second);
                else q2.push_front(it.second);

        reverse(vect.begin(),vect.end());

        if((int)vect.size()<2)
         break;

        stable_sort(vect.begin(),vect.end(),cmp);



        pair<int,pair<int,int> > pr1=vect[0];
        pair<int,pair<int,int> > pr2=vect[1];


        if(pr1.first==1) q.pop_front();
            else q2.pop_front();
        if(pr2.first==1) q.pop_front();
            else q2.pop_front();

        currentNode++;

        g[currentNode].push_back(pr1.second.first);
        g[currentNode].push_back(pr2.second.first);

        q2.push_back(make_pair(currentNode,pr1.second.second+pr2.second.second));

    }

    //printf("%d\n",g[11].size());

    //return 0;
    dfs(currentNode,0,0);

    sort(sol.begin(),sol.end());

    long long ans=0;

    for(auto it:sol)
    {
  //      printf("%d %d\n",it.second.first,it.second.second);
        ans=ans+frecv[it.first]*it.second.first;
    }

    printf("%lld\n",ans);


    for(auto it:sol)
    {
        printf("%d %lld\n",it.second.first,it.second.second);
    }
    return 0;
}