标签:字典序 const 答案 pre scan string 存储 ref break
将字母看做点,将相邻字母见看做有连一条无向边,最终判断能否形成一条由n+1个点构成的路径,即是否存在一条欧拉路或欧拉回路。
由于要字典序最小,所以按字典序从小到大遍历,找最小的字母为起点,每次找最小的字母作为下一个点。
由于欧拉(回)路是倒序存储的,所以输出答案时需要倒着输出。
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> using namespace std; const int N=2000,M=50000+100; bool e[100][100]; int deg[100]; int c(char a){ if(a>=‘a‘&&a<=‘z‘) return a-‘a‘+27; return a-‘A‘+1; } char pout(int a){ if(a>=1&&a<=26) printf("%c",a+‘A‘-1); else printf("%c",a+‘a‘-27); } int ans[100000],t; int root=(1<<30); void dfs(int u){ for(int i=1;i<=52;i++){ if(e[u][i]||e[i][u]){ e[u][i]=e[i][u]=0; dfs(i); } } ans[++t]=u; } int main(){ int n; scanf("%d",&n); for(int i=1;i<=n;i++){ char u,v; cin>>u>>v; e[c(u)][c(v)]=e[c(v)][c(u)]=1; deg[c(v)]++,deg[c(u)]++; } int cnt=0; for(int i=1;i<=52;i++) if(deg[i]%2) { cnt++;root=min(root,i); } if(cnt!=2&&cnt) { printf("No Solution\n");return 0; } if(!cnt) { for(int i=1;i<=52;i++) if(deg[i]) { root=i;break; } } dfs(root); for(int i=t;i>=1;i--){ pout(ans[i]); } return 0; }
标签:字典序 const 答案 pre scan string 存储 ref break
原文地址:https://www.cnblogs.com/Loi-Brilliant/p/9124313.html