[luogu1341] 无序字母对
欧拉路径模板,但是细节有点多……
存在欧拉路径的条件:
- 图连通 : 使用并查集维护
- 只有两个点的度为奇数,或者没有一个点
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 1005
bool vis[MAXN];
int fa[MAXN];
int dre[MAXN];
bool G[MAXN][MAXN];
int st[MAXN],top = 0;
int N;
inline int f1(char ch) {
return ch > 'Z' ? ch - 'a' + 27 : ch - 'A' + 1;
}
inline char f2(int num) {
return num > 26 ? num - 27 + 'a' : num - 1 + 'A';
}
int find(int x) {
return fa[x] == x ? x : fa[x] = find(fa[x]);
}
inline void merge(int u,int v) {
if(find(u)==find(v)) return;
fa[find(u)] = find(v);
}
inline int get_ch() {
char ch = getchar();
while(ch<'A'||(ch>'Z'&&ch<'a')||ch>'z') ch = getchar();
return f1(ch);
}
void dfs(int u) {
for(int i=1;i<MAXN;++i) {
if(!vis[i]) continue;
if(!G[u][i]) continue;
G[u][i] = G[i][u] = false;
dfs(i);
}
st[++top] = u;
}
int main() {
int u,v;
std::memset(G,0,sizeof(G));
std::memset(dre,0,sizeof(dre));
std::memset(vis,false,sizeof(vis));
for(int i=1;i<MAXN;++i) fa[i] = i;
scanf("%d",&N);
for(int i=1;i<=N;++i) {
u = get_ch(); v = get_ch();
G[u][v] = G[v][u] = true;
dre[u] ++; dre[v] ++;
vis[u] = vis[v] = true;
merge(u,v);
}
bool flag = true;
int last = -1;
int count = 0;
int first = -1;
for(int i=1;i<MAXN;++i) {
if(!vis[i]) continue;
if(last==-1) last = find(i);
else if(find(i)!=last) {
flag = false;
break;
}
if((dre[i]&1)==1) {
if(first==-1) first = i;
count ++;
}
}
if(count!=0&&count!=2) flag = false;
if(count==0) {
for(int i=1;i<MAXN;++i) {
if(vis[i]) {
first = i;
break;
}
}
}
if(!flag) {
puts("No Solution");
return 0;
}
dfs(first);
for(int i=top;i>0;--i) printf("%c",f2(st[i]));
return 0;
}