一道比较经典的欧拉回路的题。
首先n最大为C(2, 52),所以用邻接矩阵存图最好,这样还能保证得到的欧拉路径字典序最小。
对于每个字母对,就连一条无向边。然后跑欧拉路径或回路即可。
刚开始我只判了欧拉回路,忘记还可能存在欧拉路径,于是WA了几发。
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdlib> 7 #include<cctype> 8 #include<vector> 9 #include<stack> 10 #include<queue> 11 using namespace std; 12 #define enter puts("") 13 #define space putchar(' ') 14 #define Mem(a, x) memset(a, x, sizeof(a)) 15 #define rg register 16 typedef long long ll; 17 typedef double db; 18 const int INF = 0x3f3f3f3f; 19 const db eps = 1e-8; 20 const int maxn = 52 + 5; 21 const int maxm = 1.5e3 + 5; 22 inline ll read() 23 { 24 ll ans = 0; 25 char ch = getchar(), last = ' '; 26 while(!isdigit(ch)) {last = ch; ch = getchar();} 27 while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();} 28 if(last == '-') ans = -ans; 29 return ans; 30 } 31 inline void write(ll x) 32 { 33 if(x < 0) x = -x, putchar('-'); 34 if(x >= 10) write(x / 10); 35 putchar(x % 10 + '0'); 36 } 37 38 int n, s = 52, G[maxn][maxn]; 39 int du[maxn]; 40 char c[2]; 41 42 int ans[maxm], cnt = 0; 43 void dfs(int now) 44 { 45 for(int i = 0; i < 52; ++i) 46 { 47 if(G[now][i]) 48 { 49 G[now][i]--; G[i][now]--; 50 dfs(i); 51 ans[++cnt] = i; 52 } 53 } 54 } 55 56 int main() 57 { 58 n = read(); 59 for(int i = 1; i <= n; ++i) 60 { 61 scanf("%s", c); 62 int x = c[0] >= 'a' ? c[0] - 'a' + 26 : c[0] - 'A'; 63 int y = c[1] >= 'a' ? c[1] - 'a' + 26 : c[1] - 'A'; 64 G[x][y]++; G[y][x]++; 65 du[x]++; du[y]++; 66 } 67 int _cnt = 0; 68 for(int i = 0; i < 52; ++i) 69 if(du[i] & 1) 70 { 71 s = min(s, i); 72 if(++_cnt > 2) {puts("No Solution"); return 0;} 73 } 74 if(!_cnt) for(int i = 0; i < 52; ++i) 75 if(du[i]) {s = i; break;} 76 dfs(s); ans[++cnt] = s; 77 for(int i = cnt; i; --i) putchar(ans[i] >= 26 ? ans[i] - 26 + 'a' : ans[i] + 'A'); 78 enter; 79 return 0; 80 }