poj 1386 欧拉路径
1 /* 2 题意:给出N个单词,一个单词的头字母和另一个单词的尾字母相同则可以相连,问这N个单词是否能完全相连成一行 3 4 题解:求欧拉路径 5 首先以每个单词的首字母和尾字母为点并且连边,然后用DFS求该图是否连通,然后根据点的入度和出度判断是否存在 6 欧拉路径或者欧拉回路(存在回路也是符合要求的) 7 */ 8 #include <cstdio> 9 #include <cstring> 10 11 int map[30][30]; 12 int in[30],out[30]; 13 14 bool exist[30],vis[30]; 15 16 void dfs(int u) 17 { 18 vis[u] = true; 19 for(int i=0; i<26; i++) 20 if (map[u][i] && exist[i] && !vis[i]) 21 dfs(i); 22 } 23 24 int main(void) 25 { 26 int t; 27 scanf("%d",&t); 28 char str[1005]; 29 while (t--) 30 { 31 int n; 32 scanf("%d",&n); 33 memset(map,0,sizeof(map)); 34 memset(in,0,sizeof(in)); 35 memset(out,0,sizeof(out)); 36 memset(exist,false,sizeof(exist)); 37 38 for(int i=0; i<n; i++) 39 { 40 scanf("%s",str); 41 int len = strlen(str); 42 int u = str[0]-'a', v = str[len-1]-'a'; 43 map[u][v]++; 44 in[v] ++; 45 out[u] ++; 46 exist[u] = exist[v] = true; 47 } 48 49 50 // 找出合适的起点进行DFS,入度小于出度的肯定是起点,要么就任意起点 51 memset(vis,false,sizeof(vis)); 52 int i; 53 for(i=0; i<26; i++) 54 if (exist[i]) 55 break; 56 for(int j=i+1; j<26; j++) 57 if (exist[j] && in[j] < out[j]) 58 { 59 i = j; 60 break; 61 } 62 dfs(i); 63 for(i=0; i<26; i++) // 连通则所有点都遍历了 64 if (exist[i] && !vis[i]) 65 break; 66 67 bool flag = false; 68 if (i >= 26) 69 { 70 int head = 0,tail = 0,mid = 0, sum = 0; 71 for(int i=0; i<26; i++) 72 { 73 if (exist[i]) 74 { 75 sum++; 76 if (in[i] == out[i]) 77 mid++; 78 if (in[i] - out[i] == -1) 79 head++; 80 if (in[i] - out[i] == 1) 81 tail++; 82 } 83 } 84 if (sum == mid || (head == 1 && tail == 1 && mid == sum-2)) // 判断欧拉路径或回路 85 flag = true; 86 } 87 88 if (flag) 89 printf("Ordering is possible.\n"); 90 else 91 printf("The door cannot be opened.\n"); 92 } 93 return 0; 94 }