标签:
把每个字母看成一个结点,每个单词看成一条从第一个字母到最后一个字母的有向边。把这些单词首尾相接相当于寻找欧拉路径(一笔画)。
则其需满足两个条件:1.忽略边的方向后,原图联通。2.一个点的入度比出度大1,另一个点入度比出度小1,其他点入度和出度相等。
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 int in[30],out[30],n; 5 bool b[30],map[30][30]; 6 void dfs(int p) 7 { 8 int i,j,k; 9 b[p]=1; 10 for (i=0;i<=25;i++) 11 if (map[p][i]&&!b[i]) 12 dfs(i); 13 } 14 bool ok() 15 { 16 int i,j,k,x,y,z; 17 bool b1,b2; 18 b1=b2=0; 19 for (i=0;i<=25;i++) 20 if (in[i]!=out[i]) 21 { 22 if (in[i]==out[i]+1) 23 { 24 if (!b1) 25 b1=1; 26 else 27 return 0; 28 } 29 else 30 { 31 if (in[i]==out[i]-1) 32 { 33 if (!b2) 34 b2=1; 35 else 36 return 0; 37 } 38 else return 0; 39 } 40 } 41 if (b1!=b2) return 0; 42 i=0; 43 while (in[i]==0&&out[i]==0) i++; 44 dfs(i); 45 for (i=0;i<=25;i++) 46 if ((in[i]||out[i])&&!b[i]) return 0; 47 return 1; 48 } 49 int main() 50 { 51 int i,j,k,m,p,q,x,y,z,t; 52 char s[100010]; 53 scanf("%d",&t); 54 for (i=1;i<=t;i++) 55 { 56 memset(in,0,sizeof(in)); 57 memset(out,0,sizeof(out)); 58 memset(b,0,sizeof(b)); 59 memset(map,0,sizeof(map)); 60 scanf("%d\n",&n); 61 for (j=1;j<=n;j++) 62 { 63 gets(s); 64 map[s[0]-‘a‘][s[strlen(s)-1]-‘a‘]=map[s[strlen(s)-1]-‘a‘][s[0]-‘a‘]=1; 65 in[s[strlen(s)-1]-‘a‘]++; 66 out[s[0]-‘a‘]++; 67 } 68 if (ok()) printf("Ordering is possible.\n"); 69 else printf("The door cannot be opened.\n"); 70 } 71 }
标签:
原文地址:http://www.cnblogs.com/AwesomeOrion/p/5281840.html