这题的本质是欧拉通路的思想. 不过还需要并查集来判断是否是联通图, 用trie存储所有的字符串. #include <iostream> using namespace std; #define swap(i,j) {int temp=i; i = j; j = temp;} struct Node { int index; Node* arr[26]; Node() { index = -1; memset(arr, 0, sizeof(arr)); } }; int parent[500001]; int degree[500001]; Node* root = new Node(); //根节点 int words_count = 0; //不同的单词的总的个数 int get_num(char* str) { Node* p = root; while(*str) { int index = *str-'a'; if(!p->arr[index]) p->arr[index] = new Node(); p = p->arr[index]; str++; } if(p->index == -1) p->index = words_count++; return p->index; } int ufset_find(int i) { int p = i; while(parent[p] >= 0) p = parent[p]; while(i != p) { parent[i] = p; i = parent[i]; } return p; } void ufset_union(int i, int j) { i = ufset_find(i); j = ufset_find(j); if(i == j) return; if(parent[i] < parent[j]) swap(i, j); parent[i] += parent[j]; //注意这两行的先后顺序! parent[j] = i; } int main() { memset(parent, -1, sizeof(parent)); memset(degree, 0, sizeof(degree)); char str1[11], str2[11]; while(scanf("%s %s", str1, str2) != EOF) { int i = get_num(str1); int j = get_num(str2); degree[i]++; degree[j]++; ufset_union(i, j); } if(!words_count) { printf("Possible/n"); return 0; } if(parent[ufset_find(0)] + words_count) { printf("Impossible/n"); return 0; } int cnt = 0; for(int i = 0; i < words_count; ++i) if(degree[i]&1) cnt++; if(cnt == 2 || cnt == 0) printf("Possible/n"); else printf("Impossible/n"); return 0; }