1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
| #include <bits/stdc++.h>
#define USE_CPPIO() ios_base::sync_with_stdio(0); cin.tie(0)
#define INF 0x3f3f3f3f
#define NINF 0xc0c0c0c0
using namespace std;
int n, dsu[26], cnt, tot, indeg[26], outdeg[26];
bool vis[26], used[26][1005];
vector<string> g[26], ans;
void init() {
cnt = 1, tot = 0;
memset(indeg, 0, sizeof(indeg));
memset(outdeg, 0, sizeof(outdeg));
memset(vis, false, sizeof(vis));
memset(used, false, sizeof(used));
for(int i = 0; i < 26; ++i) {
g[i].clear();
dsu[i] = i;
}
ans.clear();
}
int Find(int x) {
if(dsu[x] == x) return x;
return dsu[x] = Find(dsu[x]);
}
void euler(int u) {
for(int i = 0; i < g[u].size(); ++i) {
int v = g[u][i][g[u][i].length() - 1] - 'a';
if(!used[u][i]) {
used[u][i] = true;
euler(v);
ans.push_back(g[u][i]);
}
}
}
bool solve() {
if(cnt != tot) return false;
int t = INF, odd = 0, q;
for(int i = 0; i < 26; ++i) {
if(g[i].size()) t = min(t, i);
if(outdeg[i] - indeg[i] == 1) {
++odd;
q = i;
}
else if(indeg[i] - outdeg[i] == 1) ++odd;
else if(indeg[i] != outdeg[i]) return false;
if(odd > 2) return false;
}
if(!odd) euler(t);
else euler(q);
for(int i = ans.size() - 1; i > 0; --i) cout << ans[i] << ".";
cout << ans[0] << endl;
return true;
}
int main() {
USE_CPPIO();
int T;
cin >> T;
while(T--) {
init();
cin >> n;
for(int i = 0; i < n; ++i) {
string s;
cin >> s;
int u = s[0] - 'a', v = s[s.length() - 1] - 'a';
if(!vis[u]) {
vis[u] = true;
++tot;
}
if(!vis[v]) {
vis[v] = true;
++tot;
}
++indeg[v];
++outdeg[u];
g[u].push_back(s);
int x = Find(u), y = Find(v);
if(x != y) {
dsu[x] = y;
++cnt;
}
}
for(int i = 0; i < 26; ++i) sort(g[i].begin(), g[i].end());
if(!solve()) cout << "***\n";
}
return 0;
}
|