Withidzaki will not be deprecated II (Harman encoding, priority queue), fuman
Description
You are excited to summon an alien creature and think that you can transform into a super person with powerful power to defeat all monsters. However, you are stunned at the face of a tall alien creature, because, do you understand M78 Xingyun? However, don't worry, because the hacker is very witty, he gave a key note: "To be honest, Japanese is a universal language, so why don't I try to speak Japanese with aliens ?"
However, what aliens say now is "! @ # $ % ^ & % # % I &!......" How do you convert such a thing into Japanese?
A set of universal conversion algorithms is the conversion of Huffman encoding! Of course, this is certainly not a normal Huffman encoding conversion, but conversion to different Kana based on different encoding lengths.
Input
The first behavior is an integer t, followed by t rows of data. 1 <= t <= 100
Each group of input data is an alien string. For convenience, uppercase and lowercase English letters are used to replace alien letters. String Length cannot exceed 2000
Output
For each group of data, the total length of the binary Huffman encoding is output.
Input example
2abababacabcdefg
Output example
1220
Source of http://biancheng.love/contest/23/problem/D/index
Solution: In the previous construction of the Harman tree and the coding and decoding of the Harman tree, the methods of the Harman coding were described. Now we need to get the length of the Harman encoding. Recall the algorithm in the decoding process. If it is a 0-left search, if it is a 1-right search. Therefore, a character occupies a leaf node in a constructed Harman tree. It means the lowest-end of each branch of the tree. Therefore, the length of each character is the depth of the character in the Harman tree. Hope to understand this.
After understanding that the character length is the character depth, start to re-analyze the construction process of the Harman tree. During the creation of the Harman tree, the statistics on the Occurrence Frequency of each character are designed. Different occurrences of the tree correspond to different depths, that is, different lengths.
The procedure is as follows:
1. Retrieve the two minimum frequencies and obtain the value of the parent node based on the optimal binary tree rule (left child <parent node <right child, put this value in the above frequency (equivalent to merging two minimum two frequencies)
2. Follow the above rules for repeated merger and replacement.
3. Get the Harman tree.
Through the above analysis, we can obtain two minimum frequencies each time. How can we achieve the minimum two frequencies each time? Arrays can be used, but sorting is required each time, which is troublesome and time-consuming. Random Algorithms of the I-th sequence statistic can be used, but the complexity is also very high. What structure can we choose? This is what we have mentioned before.Priority queue
The process of using the priority queue:
1. First, we need to calculate the frequency of occurrence of each letter in the string. Because the problem has been simplified in the question, the characters are limited to lowercase letters a to lowercase letters z,
2. The frequency of occurrence from initialization a to z is 0. Therefore, After calculating the frequency, you need to push the characters that appear into the queue with the condition that the frequency is not 0.
3. Add the smallest two values to the priority queue each time. The condition for exiting the loop is that the priority queue is empty.
The following code is provided:
# Include <bits/stdc ++. h ># define max_size 10010 using namespace std; typedef long LL; char c [max_size]; long f [max_size]; priority_queue <LL, vector <LL>, greater <LL> q; // create a small top heap; long n, ans; int main () {int n; scanf ("% d", & n ); while (n --) {string s; cin> s; getchar (); memset (f, 0, sizeof (f); int lens = s. size (); for (int I = 1; I <= lens; I ++) {c [I] = s [I-1]; f [c [I] ++;} while (! Q. empty () q. pop (); for (int I = 65; I <= 122; I ++) {if (f [char (I)]> 0) {sum ++; q. push (f [char (I)]);} ans = 0; while (q. size ()> 1) {LL a = q. top (); q. pop (); LL B = q. top (); q. pop (); ans + = (a + B); // q. push (a + B);} printf ("% lld \ n", ans);} return 0 ;}
We can find that the previous statistical frequency is not only for the statistical frequency, but also for pushing it into the priority queue.
The following shows the code for solving the problem according to the user tree. The advantages and disadvantages of the two methods can be compared:
1 # include <iostream> 2 # include <cstdio> 3 # include <cmath> 4 # include <cstdlib> 5 # include <algorithm> 6 # include <iomanip> 7 # include <cstring> 8 # include <string> 9 # define INF 0 xFFFFFF 10 using namespace std; 11 12 typedef struct 13 {14 int parent [1005]; 15 int lchild [1005]; 16 int rchild [1005]; 17 int weight [1005]; 18} Htree; 19 20 int createHt (Htree & ht) 21 {22 int n = 0; // length; 23 int Min1, min2; 24 int lchild, rchild; 25 memset (ht. parent,-1, sizeof (ht. parent); 26 memset (ht. lchild,-1, sizeof (ht. lchild); 27 memset (ht. rchild,-1, sizeof (ht. rchild); 28 memset (ht. weight, 0, sizeof (ht. weight); 29 30 string str; 31 cin> str; 32 int uppercase [26], lowercase [26]; 33 memset (uppercase, 0, sizeof (uppercase )); 34 memset (lowercase, 0, sizeof (lowercase); 35 for (int I = 0; I <str. length (); I ++) 36 {37 if (str [I] <91) // uppercase 38 uppercase [str [I]-65] ++; 39 else 40 lowercase [str [I]-97] ++; 41} 42 for (int I = 0; I <26; I ++) 43 {44 if (uppercase [I]! = 0) 45 ht. weight [n ++] = uppercase [I]; 46} 47 for (int I = 0; I <26; I ++) 48 {49 if (lowercase [I]! = 0) 50 ht. weight [n ++] = lowercase [I]; 51} 52 53 for (int I = n; I <2 * n-1; I ++) 54 {55 min1 = min2 = INF; 56 lchild = rchild =-1; 57 for (int j = 0; j <I; j ++) 58 {59 if (ht. parent [j] =-1) 60 {61 if (ht. weight [j] <min1) 62 {63 min2 = min1; 64 rchild = lchild; 65 min1 = ht. weight [j]; 66 lchild = j; 67} 68 else if (ht. weight [j] <min2) 69 {70 min2 = ht. weight [j]; 71 rchild = j; 72} 73} 74} 75 ht. weight [I] = ht. weight [lchild] + Ht. weight [rchild]; 76 ht. lchild [I] = lchild; 77 ht. rchild [I] = rchild; 78 ht. parent [lchild] = ht. parent [rchild] = I; 79} 80 return n; 81} 82 83 int main () 84 {85 int T; 86 Htree ht; 87 long result; 88 int level; 89 cin> T; 90 while (T --) 91 {92 int len = createHt (ht); 93 result = 0; 94 for (int I = 0; I <len; I ++) 95 {96 level = 0; 97 int j = I; 98 while (ht. parent [j]! =-1) 99 {100 level ++; 101 j = ht. parent [j]; 102} 103 result + = level * ht. weight [I]; 104} 105 printf ("% lld \ n", result); 106} 107}View Code