本题是将首尾的字母作为点,每个单词就是表示首尾字母是连通的,例如acm中,就可以看作ac是连通的 #include<stdio.h> #include<string.h> #define N 1050 int map[N][N], in[N], out[N], vis[N]; int n, m; void dfs(int u) { vis[u] = 1; for(int i = 0;i < N; i++) if(!vis[i] && map[u][i]) }//深搜,将点连通 int main(){ scanf("%d", &n); while(n--){ char str[1050]; scanf("%d", &m); memset(map, 0, sizeof(map)); memset(in, 0, sizeof(in)); memset(out, 0, sizeof(out)); for(int i = 0;i < m; i++){ scanf("%s", &str); map[str[0] - 'a'][str[strlen(str) - 1] - 'a']++; in[str[strlen(str) - 1] - 'a']++;//入度度数 out[str[0] - 'a']++;//出度度数 } int num1 = 0, num2 = 0; int flag1 = 1, flag2 = 1; for(int i = 0;i < N; i++) { if(flag1 == 0) break; if(out[i] != in[i]) if(in[i] == out[i] + 1) { num1++; } else if(out[i] == in[i] + 1) { num2++; } else { flag1 = 0; break; } }//判断奇数点的个数,与是否都是偶数点 if(num1 && num2 && num1 + num2 > 2) flag1 = 0; if(flag1){ memset(vis, 0, sizeof(vis)); for(int i = 0;i < N; i++) if(out[i]) { dfs(i); break; } for(int i = 0;i < N; i++) { if(in[i] && !vis[i]) { flag2 = 0; break; } if(out[i] && !vis[i]) { flag2 = 0; break; } }//判断是否有度数的点都有遍历到 if(flag2) printf("Ordering is possible.\n"); else printf("The door cannot be opened.\n"); } else printf("The door cannot be opened.\n"); } return 0; } 关于欧拉路径和欧拉回路的,有向的欧拉路径,其所有的节点的度数都为偶数, 或者其中有两个点的度数为奇数,一个的入度比出度少1,另一个的出度比入度少1,其余的点的度数都为偶数