Play on Words 欧拉通路(回路)判断
note: 判断一下连通性。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <string> 7 #include <vector> 8 #include <set> 9 #include <map> 10 #include <stack> 11 #include <queue> 12 #include <sstream> 13 #include <iomanip> 14 using namespace std; 15 typedef long long LL; 16 const int INF=0x4fffffff; 17 const int EXP=1e-5; 18 const int MS=100005; 19 const int SIZE=26; 20 21 int n; 22 char word[MS]; 23 int od[SIZE],id[SIZE]; 24 25 int appear[SIZE]; 26 int fa[SIZE]; 27 28 struct edge 29 { 30 int u,v; 31 }edges[MS]; 32 33 void fa_init() 34 { 35 for(int i=0;i<SIZE;i++) 36 fa[i]=-1; 37 } 38 39 int find(int x) 40 { 41 int s; 42 for(s=x;fa[s]>=0;s=fa[s]); 43 44 while(s!=x) 45 { 46 int tmp=fa[x]; 47 fa[x]=s; 48 x=tmp; 49 } 50 return s; 51 } 52 53 void merge(int x,int y) 54 { 55 int f1=find(x); 56 int f2=find(y); 57 int tmp=fa[f1]+fa[f2]; 58 if(fa[f1]>fa[f2]) 59 { 60 fa[f1]=f2; 61 fa[f2]=tmp; 62 } 63 else 64 { 65 fa[f2]=f1; 66 fa[f1]=tmp; 67 } 68 } 69 70 bool connect() 71 { 72 int u,v,i; 73 fa_init(); 74 for(i=0;i<n;i++) 75 { 76 u=edges[i].u; 77 v=edges[i].v; 78 if(u!=v&&find(u)!=find(v)) 79 merge(u,v); 80 } 81 82 int first=-1; 83 for( i=0;i<SIZE;i++) 84 { 85 if(appear[i]==0) 86 continue; 87 if(first==-1) 88 first=i; 89 else if(find(i)!=find(first)) 90 break; 91 } 92 if(i<SIZE) 93 return false; 94 return true; 95 } 96 97 int main() 98 { 99 int u,v; 100 int i,j; 101 int T; 102 scanf("%d",&T); 103 while(T--) 104 { 105 memset(od,0,sizeof(od)); 106 memset(id,0,sizeof(id)); 107 memset(appear,0,sizeof(appear)); 108 scanf("%d",&n); 109 for(i=0;i<n;i++) 110 { 111 scanf("%s",word); 112 u=word[0]-'a'; 113 v=word[strlen(word)-1]-'a'; 114 od[u]++; 115 id[v]++; 116 117 appear[u]=appear[v]=1; 118 edges[i].u=u; 119 edges[i].v=v; 120 } 121 122 bool Euler=true; 123 int one=0,none=0; 124 for(i=0;i<SIZE;i++) 125 { 126 if(appear[i]==0) 127 continue; 128 if(od[i]-id[i]>=2||id[i]-od[i]>=2) 129 { 130 Euler=false; 131 break; 132 } 133 if(od[i]-id[i]==1) 134 { 135 one++; 136 if(one>1) 137 { 138 Euler=false; 139 break; 140 } 141 } 142 if(id[i]-od[i]==1) 143 { 144 none++; 145 if(none>1) 146 { 147 Euler=false; 148 break; 149 } 150 } 151 } 152 if(one!=none) 153 Euler=false; 154 if(connect()==false) 155 Euler=false; 156 if(Euler) 157 printf("Ordering is possible.\n"); 158 else 159 printf("The door cannot be opened.\n"); 160 } 161 return 0; 162 }