【字典树】CODEFORCES 566A Matching Names
题意:n个A串,n个B串,求如何匹配使得LCP和最大。
思路:裸的字典树,当时想复杂了。。。
代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <vector> 4 #include <algorithm> 5 6 using namespace std; 7 8 struct Trie { 9 int next[900000][26]; 10 vector<int> vec[900000][2]; 11 int L, root; 12 int newnode() { 13 for(int i = 0; i < 26; ++i) 14 next[L][i] = -1; 15 return L++; 16 } 17 void init() { 18 L = 0; 19 root = newnode(); 20 } 21 void insert(char buf[], int id, int v) { 22 int len = strlen(buf); 23 int now = root; 24 vec[now][id].push_back(v); 25 for(int i = 0; i < len; ++i) { 26 if(next[now][buf[i]-'a'] == -1) 27 next[now][buf[i]-'a'] = newnode(); 28 now = next[now][buf[i]-'a']; 29 vec[now][id].push_back(v); 30 } 31 } 32 }; 33 34 int n; 35 Trie T; 36 char a[900000]; 37 bool vis[2][100007]; 38 int Match[100007]; 39 40 int dfs(int dep, int u) { 41 int ans = 0; 42 for (int i = 0; i < 26; ++i) if (T.next[u][i] != -1) 43 ans += dfs(dep + 1, T.next[u][i]); 44 vector<int> now[2]; 45 for (int i = 0; i < 2; ++i) 46 for (size_t j = 0; j < T.vec[u][i].size(); ++j) 47 if (!vis[i][T.vec[u][i][j]]) now[i].push_back(T.vec[u][i][j]); 48 int len = min(now[0].size(), now[1].size()); 49 ans += dep * len; 50 for (int i = 0; i < len; ++i) { 51 Match[now[0][i]] = now[1][i]; 52 vis[0][now[0][i]] = vis[1][now[1][i]] = true; 53 } 54 return ans; 55 } 56 57 int main() { 58 T.init(); 59 scanf("%d", &n); 60 for (int i = 1; i <= n; ++i) { 61 scanf("%s", a); 62 T.insert(a, 0, i); 63 } 64 for (int i = 1; i <= n; ++i) { 65 scanf("%s", a); 66 T.insert(a, 1, i); 67 } 68 int ans = dfs(0, 0); 69 printf("%d\n", ans); 70 for (int i = 1; i <= n; ++i) 71 printf("%d %d\n", i, Match[i]); 72 return 0; 73 }