You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

67 lines
1.9 KiB

2 years ago
#include <bits/stdc++.h>
using namespace std;
const int N = 30;
int m;
int din[N], dout[N], p[N];
bool st[N];
int find(int x) {
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
int main() {
char str[1010];
int T;
scanf("%d", &T);
while (T--) {
scanf("%d", &m);
memset(din, 0, sizeof din);
memset(dout, 0, sizeof dout);
memset(st, 0, sizeof st);
for (int i = 0; i < 26; i++) p[i] = i;
for (int i = 0; i < m; i++) {
scanf("%s", str);
int len = strlen(str);
int a = str[0] - 'a', b = str[len - 1] - 'a';
st[a] = st[b] = 1;
dout[a]++, din[b]++;
p[find(a)] = find(b);
}
// 利用欧拉图判断的定理检查
int start = 0, s = 0, e = 0, flag = 1; // start:起点s:起点个数,e:终点个数
for (int i = 0; i < 26; i++)
if (din[i] != dout[i]) { // 如果入度与出度不相等,那么必须是一个起点,一个终点
if (din[i] == dout[i] - 1) // 入度=出度-1 ->起点
start = i, s++; // 记录起点
else if (din[i] == dout[i] + 1) // 入度=出度+1 ->终点
e++;
else { // 没有欧拉通路,标识start=-1,表示检查失败
start = -1;
break;
}
}
if (start == -1 || s > 1 || e > 1) flag = 0;
// 判连通
for (int i = 0; i < 26; i++) {
if (!st[i]) continue; // 只处理出现的点
if (find(start) != find(i)) { // 找到不是一个家庭的成员
flag = 0;
break;
}
}
if (flag)
puts("Ordering is possible.");
else
puts("The door cannot be opened.");
}
return 0;
}