Codeforces Round #288 (Div. 2) D. Tanya and Password (Euler's path ),
Address: http://codeforces.com/contest/508/problem/D
The first question to output the Euler's path. Search by dfs.
Split each word into the first two groups, the last two groups, and then add edges and labels to the two groups. For example, "abc" is split into "AB" and "bc", and an edge is added to the numbers of AB and bc. Then, perform a deep search and record the path. It should be noted that, if you use the forward star, you need to perform further search so that you do not have to go behind the side that you walked in front of it, and you also need to trace back the time when you walked in front of it. Just do it.
The Code is as follows:
#include <iostream>#include <string.h>#include <math.h>#include <queue>#include <algorithm>#include <stdlib.h>#include <map>#include <set>#include <stdio.h>using namespace std;#define LL __int64#define pi acos(-1.0)const int mod=1e9+7;const int INF=0x3f3f3f3f;const double eqs=1e-9;int in[4000], out[4000], cnt, head[4000], tot, vis[210000], path[210000], top;char st[210000][4];int id[4000];struct node { int u, v, next;} edge[410000];void add(int u, int v){ edge[cnt].v=v; edge[cnt].next=head[u]; head[u]=cnt++;}void dfs(int u, int id){ for(int i=head[u]; i!=-1; i=edge[i].next) { if(!vis[i]) { vis[i]=1; head[u]=i; dfs(edge[i].v,i); } i=head[u]; } path[top++]=id;}int getid(char *s){ int ans=0,tmp; for(int i=0;i<2;i++){ if(s[i]>='a'&&s[i]<='z') tmp=s[i]-'a'; else if(s[i]>='A'&&s[i]<='Z') tmp=s[i]-'A'+26; else tmp=s[i]-'0'+52; ans=ans*62+tmp; } return ans;}void init(){ memset(in,0,sizeof(in)); memset(out,0,sizeof(out)); memset(head,-1,sizeof(head)); memset(vis,0,sizeof(vis)); memset(id,0,sizeof(id)); cnt=tot=0;}int main(){ int n, i, flag, sum=0, pos, num1, num2; char s1[3], s2[3]; scanf("%d",&n); init(); getchar(); for(i=0; i<n; i++) { gets(st[i]); s1[0]=st[i][0]; s1[1]=st[i][1]; s1[2]='\0'; s2[0]=st[i][1]; s2[1]=st[i][2]; s2[2]='\0'; num1=getid(s1); num2=getid(s2); if(!id[num1]) { id[num1]=++tot; } if(!id[num2]) { id[num2]=++tot; } //printf("%d %d\n",q[s1],q[s2]); add(id[num1],id[num2]); out[id[num1]]++; in[id[num2]]++; } //printf("%d\n",siz[1]); flag=0; pos=1; for(i=1; i<=tot; i++) { if(in[i]!=out[i]) { sum++; if(out[i]-in[i]==1) { pos=i; } } if(abs(in[i]-out[i])>1) { flag=1; break; } } if(flag||sum>2) { printf("NO\n"); } else { top=0; dfs(pos,-1); //printf("%d\n",top); if(top!=n+1) { printf("NO"); } else { printf("YES\n"); //printf("---%d\n",path[top-2]); printf("%s",st[path[top-2]]); for(i=top-3; i>=0; i--) { printf("%c",st[path[i]][2]); } } } return 0;}