题意:给出一些单词,问全部单词能否首尾相连
直接 将每一个单词第一个和最后一个字母建立一条有向边,保证除了首尾两个出入度不相等,其他的要保证相等。还有一个条件就是 首尾两个出入度差为1
同时并查集判连通
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <cstring> 5 #include <algorithm> 6 using namespace std; 7 const int Max = 100000 + 10; 8 struct Node 9 { 10 int x, y; 11 }; 12 char str[Max]; 13 Node node[Max]; 14 int indegree[30], outdegree[30]; 15 int father[30], vis[30]; 16 int find_father(int x) 17 { 18 if (x == father[x]) 19 return x; 20 return father[x] = find_father(father[x]); 21 } 22 int unionset(int x, int y) 23 { 24 x = find_father(x); 25 y = find_father(y); 26 if (x == y) 27 return false; 28 father[y] = x; 29 return true; 30 } 31 int main() 32 { 33 int T, n; 34 scanf("%d", &T); 35 while (T--) 36 { 37 scanf("%d", &n); 38 memset(indegree, 0, sizeof(indegree)); 39 memset(outdegree, 0, sizeof(outdegree)); 40 memset(vis, 0, sizeof(vis)); 41 for (int i = 0; i < 30; i++) 42 father[i] = i; 43 int setcnt = 0; 44 for (int i = 1; i <= n; i++) 45 { 46 scanf("%s", str); 47 node[i].x = str[0] - 'a'; 48 node[i].y = str[ strlen(str) - 1] - 'a'; 49 indegree[node[i].y]++; 50 outdegree[node[i].x]++; 51 vis[node[i].x] = 1; 52 vis[node[i].y] = 1; 53 if (unionset(node[i].x, node[i].y)) 54 { 55 setcnt++; 56 } 57 } 58 int numcnt = 0; 59 for (int i = 0; i < 26; i++) 60 { 61 if (vis[i]) 62 numcnt++; 63 } 64 if (setcnt != (numcnt - 1)) 65 { 66 printf("The door cannot be opened. "); 67 continue; 68 } 69 if (n == 1) 70 { 71 printf("Ordering is possible. "); 72 continue; 73 } 74 int x = 0, y = 0, z = 0; 75 for (int i = 0; i < 26; i++) 76 { 77 if (vis[i] && indegree[i] != outdegree[i]) 78 { 79 if (indegree[i] == outdegree[i] + 1) //首 80 x++; 81 else if (indegree[i] + 1 == outdegree[i]) // 尾 82 y++; 83 else 84 z++; 85 } 86 } 87 if (z) 88 printf("The door cannot be opened. "); 89 else if ( (x == 1 && y == 1) || (x == 0 && y == 0) ) // 出入度不相等 且 差为1, 或者 是环 90 printf("Ordering is possible. "); 91 else 92 printf("The door cannot be opened. "); 93 /* 94 int cnt = 0, sum = 0; 95 for (int i = 0; i < 26; i++) 96 { 97 if (indegree[i] > 0 || outdegree[i] > 0) 98 { 99 sum++; 100 if (indegree[i] == outdegree[i]) 101 cnt++; 102 } 103 } 104 if (cnt == sum || ( sum > 2 && sum - cnt == 2)) 105 printf("Ordering is possible. "); 106 else 107 printf("The door cannot be opened. "); 108 */ 109 } 110 return 0; 111 }