关键思路是不把每个字符串看成一个点,而是把每个字符串的起始点和终止点的字符看作一共点,把每一字符串的起点和终点连一条边,然后跑欧拉路径
#include<bits/stdc++.h>
#define LL long long
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 1e5 + 10;
string str;
int n;
int din[30], dout[30];
int p[30];
bool st[30];
int find(int x) {
if (p[x] != x)p[x] = find(p[x]);
return p[x];
}
int main() {
freopen("in.in", "r", stdin);
int t;
cin >> t;
while (t--) {
memset(din, 0, sizeof din);
memset(dout, 0, sizeof dout);
memset(st, 0, sizeof st);
for (int i = 0; i < 30; i++)p[i] = i;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> str;
int l = str.size();
int stt = str[0] - 'a';
int end= str[l - 1] - 'a';
st[stt] = 1, st[end] = 1;
din[end]++, dout[stt]++;
int pstt = find(stt), pend = find(end);
p[pstt] = pend;
}
bool flag = 1;
int com = 0;
for (int i = 0; i < 30; i++)if (st[i]) {
com = find(i);
break;
}
for (int i = 0; i < 30; i++) {
if (st[i] && find(i) != com)flag = 0;
}
int cnt1 = 0, cnt2 = 0,cnt3=0;
for (int i = 0; i < 30; i++) {
if (din[i] - dout[i] == 1)cnt1++;
if (dout[i] - din[i] == 1)cnt2++;
if (din[i] != dout[i])cnt3++;
}
if (flag)
if ((cnt1 == 1 && cnt2 == 1 && cnt3==2) || !cnt3)puts("Ordering is possible.");
else puts("The door cannot be opened.");
else {
puts("The door cannot be opened.");
}
}
}
浙公网安备 33010602011771号