有N个字符串,现在要求我们输出1~N个字符串的首尾相接串,并且字典序最小。
所以,首先对N个字符串sort一下,然后再是进行处理,我们可以用一个栈来维护答案,然后为了避免访问重复的字符串,所以,每个点用一个队列去进行维护,然后用过之后就弹出,复杂度为O(N)。其余的,就是欧拉通路的基本操作了。
#include <iostream> #include <cstdio> #include <cmath> #include <string> #include <cstring> #include <algorithm> #include <limits> #include <vector> #include <stack> #include <queue> #include <set> #include <map> #include <bitset> #define lowbit(x) ( x&(-x) ) #define pi 3.141592653589793 #define e 2.718281828459045 #define INF 0x3f3f3f3f #define HalF (l + r)>>1 #define lsn rt<<1 #define rsn rt<<1|1 #define Lson lsn, l, mid #define Rson rsn, mid+1, r #define QL Lson, ql, qr #define QR Rson, ql, qr #define myself rt, l, r #define pii pair<int, int> #define MP(a, b) make_pair(a, b) using namespace std; typedef unsigned long long ull; typedef unsigned int uit; typedef long long ll; const int maxN = 30; int N, in_du[maxN], out_du[maxN], root[maxN]; int fid(int x) { return x == root[x] ? x : root[x] = fid(root[x]); } bool vis[maxN]; struct Eddge { int u, to, id; Eddge(int a=0, int b=0, int c=0):u(a), to(b), id(c) {} } edge[1005]; queue<Eddge> to[maxN]; void addEddge(int u, int v, int w) { edge[w] = Eddge(u, v, w); to[u].push(Eddge(u, v, w)); out_du[u] ++; in_du[v] ++; } stack<int> st; void dfs(int u) { while(!to[u].empty()) { int v = to[u].front().to, id = to[u].front().id; to[u].pop(); dfs(v); st.push(id); } } string s[1005]; int main() { int T; scanf("%d", &T); while(T --) { scanf("%d", &N); memset(vis, false, sizeof(vis)); for(int i = 1; i <= 26; i ++) while(!to[i].empty()) to[i].pop(); for(int i = 1; i <= 26; i ++) root[i] = i; for(int i = 1; i <= 26; i ++) in_du[i] = out_du[i] = 0; for(int i = 1; i <= N; i ++) cin >> s[i]; sort(s + 1, s + N + 1); int beg = 1; for(int i = 1, len, u, v, fu, fv; i <= N; i ++) { len = (int)s[i].size(); u = s[i][0] - 'a' + 1; if(i == 1) beg = u; v = s[i][len - 1] - 'a' + 1; vis[u] = vis[v] = true; addEddge(u, v, i); fu = fid(u); fv = fid(v); if(fu ^ fv) { root[fu] = fv; } } int sum = 0; bool ok = true; for(int i = 1; i <= 26; i ++) if(vis[i] && fid(i) == i) sum ++; if(sum > 1) ok = false; sum = 0; int sta = 0, end = 0; for(int i = 1; ok && i <= 26; i ++) if(vis[i]) { if(abs(in_du[i] - out_du[i]) == 1) { sum ++; if(in_du[i] > out_du[i]) end ++; else sta ++; } else if(abs(in_du[i] - out_du[i]) > 1) ok = false; } if(sum > 2) ok = false; if(ok && (sum == 0 || (sum == 2 && sta == 1 && end == 1))) { while(!st.empty()) st.pop(); if(!sum) { dfs(beg); } else { for(int i = 1; i <= N; i ++) if(out_du[edge[i].u] > in_du[edge[i].u]) { beg = edge[i].u; break; } dfs(beg); } while(!st.empty()) { cout << s[st.top()]; st.pop(); printf(st.empty() ? "\n" : "."); } } else printf("***\n"); } return 0; } /* 1 5 aa ab aba ba bb */