题目大意:给若干个单词,问能否排成一个前一个单词的最后一个字母是下一个单词的开头字母的序列
解题思路:欧拉路问题,只需判断连通性与除了起点和终点外,其余结点的入度和出度是否相等
#include <cstdio>
#include <cstring>
int node[26];
int find_father(int x) {
return x != node[x] ? node[x] = find_father(node[x]) : x;
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
int outdegree[26] = {0}, indegree[26] = {0}, n;
char word[1005];
for (int i = 0; i < 26; i++)
node[i] = i;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%s", word);
int a = word[0] - 'a';
int b = word[strlen(word) - 1] - 'a';
outdegree[a]++;
indegree[b]++;
node[find_father(a)] = find_father(b); //连接结点
}
int count = 0, point;
for (int i = 0; i < 26; i++)
if ((indegree[i] || outdegree[i]) && find_father(i) == i) //找出根结点,且使其他结点都指向根结点
point = i;
for (int i = 0; i < 26; i++) { //判断是否只有叶结点的出度比入度多 1,根结点的入读比出度多 1; 是否连通
count += (indegree[i] > outdegree[i] ? indegree[i] - outdegree[i] : outdegree[i] - indegree[i]);
if ((indegree[i] || outdegree[i]) && node[i] != point) //判断是否连通
count += 5;
}
printf(count > 2 ? "The door cannot be opened.\n" : "Ordering is possible.\n");
}
return 0;
}