欧拉路径,弗罗莱算法 主要参见下面的资料:
http://blog.csdn.net/u012659423/article/details/43319245
本题给出一个字符串所有的连续3位的字符串,要求找出一个满足条件的原字符串。
把2个字符(如‘aa')为点,
每个3字符串,前2字符向后两字符连边(如'abc':'ab'--->‘bc')
原题转为求新图上的欧拉路径。
PS:注意特判图不连通的情况,注意删边。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])
#define Lson (x<<1)
#define Rson ((x<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define MAXLen (200000+10)
#define MAXN (200000+10)
#define MAXM (MAXLen)
long long mul(long long a,long long b){return (a*b)%F;}
long long add(long long a,long long b){return (a+b)%F;}
long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;}
typedef long long ll;
int n,N;
char s[4];
int pre[MAXN]={0},next[MAXM]={0},edge[MAXM],size=0;
void addedge(int u,int v)
{
edge[++size]=v;
next[size]=pre[u];
pre[u]=size;
}
int indegree[MAXN],outdegree[MAXN];
int h(char c)
{
if ('a'<=c&&c<='z') return c-'a'+1;
if ('A'<=c&&c<='Z') return c-'A'+27;
else return c-'0'+1+26+26;
}
int h(char c1,char c2)
{
return h(c1)*63+h(c2);
}
int ans[MAXLen],anstot=0,S[MAXN],tot=0;
int hash[MAXLen];
void dfs(int x)
{
Forp(x)
{
int v=edge[p];
pre[x]=next[p];
S[++tot]=v;
dfs(v);
return ;
}
}
void Fleury(int st)
{
S[++tot]=st;
while (tot)
{
int x=S[tot];
if (pre[x]) dfs(x);
else
{
ans[++anstot]=x;
tot--;
}
}
if (anstot^(n+1))
{
cout<<"NO\n";
return;
}
cout<<"YES\n";
ForD(i,anstot)
{
printf("%c",hash[ans[i]/63]);
}
printf("%c\n",hash[ans[1]%63]);
}
int main()
{
// freopen("CF508D.in","r",stdin);
// freopen(".out","w",stdout);
Fork(i,'a','z') hash[i-'a'+1]=i;
Fork(i,'A','Z') hash[i-'A'+27]=i;
Fork(i,'0','9') hash[i-'0'+1+26+26]=i;
cin>>n;
int st=0;
For(i,n)
{
scanf("%s",s);
addedge(h(s[0],s[1]),h(s[1],s[2]));
outdegree[h(s[0],s[1])]++,indegree[h(s[1],s[2])]++;
st=h(s[0],s[1]);
}
N=h('9','9');
int s1=0,s2=0,s3=0;
For(i,N)
{
int t=indegree[i]-outdegree[i];
if (t==1) ++s1;
else if (t==0) ++s2;
else if (t==-1) ++s3,st=i;
else
{
cout<<"NO\n";
return 0;
}
}
if ((s1==s3&&s3==0)||(s1==s3&&s3==1))
{
Fleury(st);
return 0;
}
cout<<"NO\n";
return 0;
return 0;
}