1 /* 2 * 并查集+字典树 3 */ 4 5 #include <cstdio> 6 #include <cstdlib> 7 #include <cstring> 8 #include <iostream> 9 10 using namespace std; 11 12 const int N = 21; 13 const int M = 200005; 14 15 int cs; 16 int parent[M]; 17 char strA[N], strB[N]; 18 struct node { 19 int c; 20 node *child[52]; 21 node() { 22 c = 0; 23 for (int i=0; i<52; ++i) child[i] = NULL; 24 } 25 }*root; 26 27 int insert(char str[]) {//字典树功能:将名字映射成代表该名字的一个整数 28 node *p = root; 29 int len = strlen(str); 30 for (int k,i=0; i<len; ++i, p=p->child[k]) { 31 if (str[i]>='a' && str[i]<='z') k = str[i] - 'a'; 32 else k = str[i] - 'A' + 26; 33 if (!p->child[k]) p->child[k] = new node(); 34 // else if (i==len-1 && p->child[k]->c>0) return p->child[k]->c; 35 } 36 if (p->c) return p->c; 37 return p->c = ++cs; 38 } 39 40 void UFset() { 41 for (int i=1; i<M; ++i) parent[i] = -1; 42 } 43 44 int Find(int x) { 45 int s; 46 for (s=x; parent[s]>0; s=parent[s]); 47 while (s != x) {//路径压缩 48 int tmp = parent[x]; 49 parent[x] = s; 50 x = tmp; 51 } 52 return s; 53 // if (parent[x] > 0) parent[x] = Find(parent[x]); 54 } 55 56 int Union(int r1, int r2) { 57 int tmp = parent[r1] + parent[r2]; 58 if (parent[r1] > parent[r2]) parent[r1] = r2, parent[r2] = tmp; 59 else parent[r2] = r1, parent[r1] = tmp; 60 return tmp; 61 } 62 63 void del(node *p) { 64 for (int i=0; i<52; ++i) { 65 if (p->child[i]) del(p->child[i]); 66 } 67 delete p; 68 p = NULL; 69 } 70 71 int main() { 72 int t; 73 while (scanf ("%d", &t) != EOF) { 74 while (t--) { 75 int n; 76 scanf ("%d", &n); 77 cs = 0; 78 UFset(); 79 root = new node(); 80 while (n--) { 81 scanf ("%s%s", strA, strB); 82 int a = insert(strA); 83 int b = insert(strB); 84 int r1 = Find(a); 85 int r2 = Find(b); 86 if (r1 != r2) printf ("%d\n", abs(Union(r1, r2))); 87 else printf ("%d\n", abs(parent[r1])); 88 } 89 del(root); 90 } 91 } 92 return 0; 93 }