题目描述
给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒)。请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现。
题解
显然我们要找一条欧拉路径或者欧拉回路,这里学习一种新算法,借用DFS栈输出答案,我们发现当我们一直DFS下去的时候可能有一些边最后没能走到,就会在回来的时候又被递归下去,我们发现这刚好是我们想要的,就是走到分界点的时候走回来又走出去所以只要在DFS只后把答案放进去即可,输出要倒序
代码
#include <bits/stdc++.h>
#define maxn 10005
#define LL long long
#define INF 0x3f3f3f3f
#define I inline
#define re register
using namespace std;
int read(){
int res; bool f=1; char c;
while(!isdigit(c=getchar())) if(c=='-') f=0; res=c^48;
while(isdigit(c=getchar())) res=(res<<3)+(res<<1)+(c^48);
return f?res:-res;
}
struct NODE{
int x,id;
bool operator < (const NODE &rhs)const{return x<rhs.x;}
};
vector<NODE> E[maxn];
vector<int> ans;
int n,s,cnt,du[maxn];
bool vis[maxn];
void DFS(int u){
for(int i=0;i<E[u].size();i++){
int v=E[u][i].x; if(vis[E[u][i].id]) continue;
vis[E[u][i].id]=1; DFS(v);
}
ans.push_back(u);
}
int main(){
n=read();
for(int i=1;i<=n;i++){
char c[3],x,y; scanf("%s",c+1); x=c[1]-'A'; y=c[2]-'A';
du[x]++; du[y]++;
E[x].push_back((NODE){y,i});
E[y].push_back((NODE){x,i});
vis[x]=1; vis[y]=1;
}
for(int i=0;i<100;i++) sort(E[i].begin(),E[i].end());
for(int i=0;i<100;i++){
if(vis[i] && du[i]&1) cnt++;
}
if(!(cnt==0||cnt==2)) {puts("No Solution"); return 0;}
if(cnt==0){
for(int i=0;i<100;i++){
if(vis[i]) {s=i; break;}
}
}
else{
for(int i=0;i<100;i++){
if(du[i]&1) {s=i; break;}
}
}
memset(vis,0,sizeof vis);
DFS(s);
if(ans.size()<n+1){puts("No Solution");}
else{for(int i=ans.size()-1;~i;i--) printf("%c",ans[i]+'A');}
return 0;
}