Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #define INF 1e9
- using namespace std;
- // ii is an ordered pair. Use .first and .second to reference the first and
- // second element respectively|
- typedef pair<int,int> ii;
- typedef long long ll;
- typedef vector<int> vi;
- typedef vector<ii> vii;
- /*
- Computes for the optimal cost of encoding the given frequencies.
- Parameters:
- -n : number of elements to encode
- -f : list of frequencies to encode
- Returns a long integer with the optimal encoding length.
- */
- ll greedy_huffman_encoding(const int &n, const vi &f) {
- // initialize min heap (C++ defaults to max heap, so we have to set
- // greater<ii> as the comparator)
- priority_queue<ii,vii,greater<ii>> pq;
- // intitialize adjacency list tree. For all n, allocate a dynamic list.
- vector<vi> adj(n,vi());
- // insert all frequencies in the min heap along with the node-id
- for(int i = 0; i < n; i++) {
- pq.push(ii(f[i],i));
- }
- // while we have more than one root node
- while(pq.size() > 1) {
- // get the two lowest frequency nodes
- ii t1 = pq.top(); pq.pop();
- ii t2 = pq.top(); pq.pop();
- // get id of new node
- int new_node = adj.size();
- // allocate new dynamic list for new node in adjacency list
- adj.push_back(vi());
- // assign t1 and t2 as children to the new node
- adj[new_node].push_back(t1.second);
- adj[new_node].push_back(t2.second);
- // add the new node to min heap with frequency equal to the
- // sum of t1 and t2's frequencies
- pq.push(ii(t1.first + t2.first,new_node));
- }
- // initialize depth array for entire tree
- vi depth(adj.size(),INF);
- // initialize queue for breadth-first traversal of tree
- queue<int> q;
- // the top of the min heap gives the id of the root of the huffman code tree
- q.push(pq.top().second);
- // initialize depth of root to zero
- depth[pq.top().second] = 0;
- // total bit encoding is initialized to zero
- ll ans = 0LL;
- // while there are unexplored nodes
- while(!q.empty()) {
- int u = q.front(); q.pop();
- // if within original nodes
- if(u < n) {
- // add the bit encoding of this frequency by multiplying the depth
- // by the frequency
- ans += depth[u] * 1LL * f[u];
- }
- // for all children
- for(auto &x : adj[u]) {
- // compute depth of child
- depth[x] = depth[u] + 1;
- // add to frontier
- q.push(x);
- }
- }
- return ans;
- }
- int main() {
- int n; // number of characters
- vi freqs; // frequency count of characters
- // get input
- scanf("%d",&n);
- freqs.assign(n,0);
- for(int i = 0; i < n; i++) {
- scanf("%d",&freqs[i]);
- }
- // print output
- printf("%lld\n",greedy_huffman_encoding(n,freqs));
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement