<pre name="code" class="cpp">/* 这是道关于欧拉回路的问题, 最前面的字母是起点,最后的字母是终点. 有向图,要想能构成欧拉路径,首先必须是联通的.所以用并查集判断是不是一个祖先来判断是否是完全联通的图. 其次要保证,它的出度和入度要全相等或者恰好两个(起点和终点)的时候 出入度差值可以为一. */ #include <stdio.h> #include <stdlib.h> #include <string.h> typedef __int64 LL; #define N 456976 int f[30]; int find(int a) { return f[a]==-1?a:f[a]=find(f[a]);} void unit(int a,int b) { int fa=find(a),fb=find(b); if(fa!=fb) { if(fb<fa) f[fa]=fb; else f[fb]=fa; } } int main() { int n,tt,i; int data[30];//是否 有该点. char a[1010]; int du[30][2];//0入度 1出度 scanf("%d",&tt); while(tt--) { memset(du,0,sizeof(du)); memset(f,-1,sizeof(f)); memset(data,0,sizeof(data)); scanf("%d",&n); for(i=0;i<n;i++) { scanf("%s",a); du[a[0]-'a'][0]++;//首字母 du[a[strlen(a)-1]-'a'][1]++;//尾字母 data[a[0]-'a']=1;//有无访问 data[a[strlen(a)-1]-'a']=1; unit(a[0]-'a',a[strlen(a)-1]-'a'); } int shu=0; for(i=0;i<26;i++) { if(du[i][0]==du[i][1]+1) shu++; else if(du[i][0]+1==du[i][1]) shu++; else if(du[i][0]!=du[i][1]) break; } if(shu>2||shu==1||i!=26)//shu表示入度和出度不相同的数目. { printf("The door cannot be opened.\n"); continue; } shu=0; for(i=0;i<26;i++) { if(find(i)==i&&data[i]==1) shu++; } if(shu==1)//祖先数 { printf("Ordering is possible.\n"); } else printf("The door cannot be opened.\n"); } return 0; }