1 #include<iostream> 2 #include<string> 3 #include<queue> 4 #include<cstdio> 5 #include<cstring> 6 #define MAXM 26 7 #define MAXN 1010 8 #define INF 123456789 9 using namespace std; 10 char str[MAXN][MAXM]; 11 string path[MAXM << 1][MAXN]; 12 int size, dp[MAXM << 1][MAXN]; 13 struct Trie { 14 int fail, cost, next[MAXM]; 15 void Init() { 16 fail = cost = 0; 17 memset(next, 0, sizeof(next)); 18 } 19 }; 20 Trie tree[MAXN]; 21 inline int GET(char ch) { 22 return ch - 'a'; 23 } 24 void Insert(char *s, int val) { 25 int now, t; 26 for (now = 0; *s; s++) { 27 t = GET(*s); 28 if (!tree[now].next[t]) { 29 tree[++size].Init(); 30 tree[now].next[t] = size; 31 } 32 now = tree[now].next[t]; 33 } 34 tree[now].cost += val; 35 } 36 void BFS() { 37 int now, i, p; 38 queue<int> q; 39 q.push(0); 40 while (!q.empty()) { 41 now = q.front(); 42 q.pop(); 43 for (i = 0; i < MAXM; i++) { 44 if (tree[now].next[i]) { 45 p = tree[now].next[i]; 46 q.push(p); 47 if (now) 48 tree[p].fail = tree[tree[now].fail].next[i]; 49 tree[p].cost += tree[tree[p].fail].cost; 50 } else 51 tree[now].next[i] = tree[tree[now].fail].next[i]; 52 } 53 } 54 } 55 void DoIt(int n) { 56 string temp; 57 int i, j, k, p, ans; 58 for (i = 0; i <= n; i++) { 59 for (j = 0; j <= size; j++) 60 path[i][j].clear(); 61 } 62 memset(dp, -1, sizeof(dp)); 63 dp[0][0] = ans = 0; 64 for (i = 1; i <= n; i++) { 65 for (j = 0; j <= size; j++) { 66 if (dp[i - 1][j] == -1) 67 continue; 68 for (k = 0; k < MAXM; k++) { 69 p = tree[j].next[k]; 70 if (dp[i][p] < dp[i - 1][j] + tree[p].cost) { 71 dp[i][p] = dp[i - 1][j] + tree[p].cost; 72 temp.clear(); 73 temp.push_back('a' + k); 74 path[i][p] = path[i - 1][j] + temp; 75 } else if (dp[i][p] == dp[i - 1][j] + tree[p].cost) { 76 temp.clear(); 77 temp.push_back('a' + k); 78 temp = path[i - 1][j] + temp; 79 if (temp < path[i][p]) 80 path[i][p] = temp; 81 } 82 ans = max(ans, dp[i][p]); 83 } 84 } 85 } 86 if (ans == 0) 87 putchar('\n'); 88 else { 89 for (i = 1; i <= n; i++) { 90 for (j = 0; j <= size; j++) { 91 if (dp[i][j] == ans) { 92 temp = path[i][j]; 93 break; 94 } 95 } 96 if (j <= size) 97 break; 98 } 99 for (j = 0; j <= size; j++) { 100 if (dp[i][j] == ans && path[i][j] < temp) 101 temp = path[i][j]; 102 } 103 cout << temp << endl; 104 } 105 } 106 int main() { 107 int c, i, n, m, val; 108 scanf("%d", &c); 109 while (c--) { 110 size = 0; 111 tree[0].Init(); 112 scanf("%d%d", &n, &m); 113 for (i = 1; i <= m; i++) 114 scanf(" %s", str[i]); 115 for (i = 1; i <= m; i++) { 116 scanf("%d", &val); 117 Insert(str[i], val); 118 } 119 BFS(); 120 DoIt(n); 121 } 122 return 0; 123 }