http://acm.split.hdu.edu.cn/showproblem.php?pid=1116
1 #include<stdio.h> 2 #include<algorithm> 3 #include<iostream> 4 #include<string.h> 5 using namespace std; 6 const int M=30; 7 int fa[M],vis[M],in[M],out[M],ans[M]; 8 char ch[1004]; 9 int fin(int x){ 10 return fa[x]==x?fa[x]:fa[x]=fin(fa[x]); 11 } 12 int unin(int x,int y) 13 { 14 15 return fa[fin(y)]=fin(x); 16 } 17 int main() 18 { 19 int t,n,a,b; 20 cin>>t; 21 while(t--){ 22 cin>>n; 23 memset(vis,0,sizeof(vis)); 24 memset(in,0,sizeof(in)); 25 memset(out,0,sizeof(out)); 26 for(int i=0;i<26;i++){///初始化父亲结点 27 fa[i]=i; 28 } 29 for(int i=0;i<n;i++){ 30 scanf("%s",ch); 31 a=ch[0]-'a'; 32 b=ch[strlen(ch)-1]-'a'; 33 unin(a,b);///把字符串的开头字母和结尾字母连结起来,即是把它看作是一条有向线段 34 out[a]++;///出度 35 in[b]++;///入度 36 vis[a]=1;///标记 37 vis[b]=1;///标记 38 } 39 for(int i=0;i<26;i++) 40 fa[i]=fin(i);0///fa存储的是每个点最终的根节点 41 int cnt=0; 42 for(int i=0;i<26;i++) 43 if(vis[i]&&fa[i]==i) 44 cnt++; 45 if(cnt>1)///cnt大于1代表除啦根节点,还有根节点没有变的节点,那么此时代表图不连通 46 { 47 48 cout<<"The door cannot be opened. "; 49 continue; 50 } 51 int j=0; 52 for(int i=0;i<26;i++){ 53 if(vis[i]&&out[i]!=in[i]) 54 ans[j++]=i; 55 } 56 if(j==0){ 57 cout<<"Ordering is possible. ";///j=0代表所有点的入度等于出度,此时形成欧拉回路 58 continue; 59 } 60 if(j==2&&((out[ans[0]]-in[ans[0]]==1&& 61 in[ans[j-1]]-out[ans[j-1]]==1) 62 ||out[ans[j-1]]-in[ans[j-1]]==1&& 63 in[ans[0]]-out[ans[0]]==1))///此处为欧拉通路的判断,是初始节点和末尾节点的度的判断,为欧拉通路 64 { 65 cout<<"Ordering is possible. "; 66 continue; 67 } 68 cout<<"The door cannot be opened. "; 69 70 71 } 72 }