POJ 1386(欧拉路)
因为要求每个单词只是用一次,还要构成串,很容易想到欧拉路。
把单词抽象成一条边,首字母和末字母为边的两个端点,判断有向图欧拉路就行了
PS:注意判断连通性,判断连通性构图需要是双向的
View Code
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 using namespace std; 5 int in[30],out[30],sum,num,n,tt,st,len; 6 bool map[30][30],vis[30]; 7 char ls[10000]; 8 void dfs(int u) 9 { 10 vis[u]=true; 11 num++; 12 for(int i=1;i<=26;i++) 13 if(map[u][i]&&!vis[i]) dfs(i); 14 } 15 bool read() 16 { 17 memset(in,0,sizeof in); 18 memset(out,0,sizeof out); 19 memset(map,0,sizeof map); 20 memset(vis,0,sizeof vis); 21 sum=0;num=0; 22 scanf("%d\n",&n); 23 for(int i=1;i<=n;i++) 24 { 25 scanf("%s",ls+1); 26 len=strlen(ls+1); 27 out[ls[1]-'a'+1]++; 28 in[ls[len]-'a'+1]++; 29 map[ls[1]-'a'+1][ls[len]-'a'+1]=map[ls[len]-'a'+1][ls[1]-'a'+1]=1; 30 } 31 32 for(int i=1;i<=26;i++) 33 { 34 if(in[i]||out[i]) sum++; 35 if(out[i]) st=i; 36 } 37 memset(vis,0,sizeof vis); 38 dfs(st);//printf("st:%d\n",st); //system("pause"); 39 if(num==sum) {return true;} 40 else return false; 41 } 42 void go() 43 { 44 int a=0,b=0; 45 for(int i=1;i<=26;i++) 46 { 47 if(in[i]==out[i]+1) b++; 48 else if(out[i]==in[i]+1) a++; 49 else if(in[i]==out[i]) continue; 50 else 51 { 52 printf("The door cannot be opened.\n"); 53 return; 54 } 55 } 56 if(a<=1&&b<=1) printf("Ordering is possible.\n"); 57 else printf("The door cannot be opened.\n"); 58 } 59 int main() 60 { 61 scanf("%d",&tt); 62 while(tt--) 63 { 64 if(!read()) printf("The door cannot be opened.\n"); 65 else go(); 66 } 67 system("pause"); 68 return 0; 69 }
没有人能阻止我前进的步伐,除了我自己!