题目描述
给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒)。请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现。
输入格式
第一行输入一个正整数n。
以下n行每行两个字母,表示这两个字母需要相邻。
输出格式
输出满足要求的字符串。
如果没有满足要求的字符串,请输出“No Solution”。
如果有多种方案,请输出前面的字母的ASCII编码尽可能小的(字典序最小)的方案
大意就是给你n条无向路,让你找一个字典序最小的欧拉路径
#include<bits/stdc++.h> #define re return #define R register #define ll long long #define inc(i,l,r) for(register int i=l;i<=r;++i) using namespace std; const int maxn=300005; char buf[1<<21],*p1,*p2; inline int gc(){re p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;} template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } int m,vis[70][70],d[70]; stack<int>s; inline void dfs(int x) { inc(i,1,70) if(vis[x][i]) { --vis[x][i]; --vis[i][x]; dfs(i); } s.push(x); } int main() { char ss[10]; int x,y; rd(m); int st=100; inc(i,1,m) { scanf("%s",ss); x=ss[0]-64;y=ss[1]-64; st=min(x,st); st=min(st,y); ++vis[x][y]; ++vis[y][x]; //可能存在不同的边连接同一条路 ++d[x]; ++d[y]; } inc(i,1,70) if(d[i]%2) { st=i; break; } int cnt=0; inc(i,1,70) if(d[i]%2)++cnt; if(cnt&&cnt!=2) { printf("No Solution"); re 0; } dfs(st); while(!s.empty()) { printf("%c",s.top()+64); s.pop(); } re 0; }
不要问我为什么没用并查集判连通,数据太弱,我也很忧伤