Catenyms
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 10186   Accepted: 2650

Description

A catenym is a pair of words separated by a period such that the last letter of the first word is the same as the last letter of the second. For example, the following are catenyms: 
dog.gopher

gopher.rat
rat.tiger
aloha.aloha
arachnid.dog

A compound catenym is a sequence of three or more words separated by periods such that each adjacent pair of words forms a catenym. For example, 

aloha.aloha.arachnid.dog.gopher.rat.tiger 

Given a dictionary of lower case words, you are to find a compound catenym that contains each of the words exactly once.

Input

The first line of standard input contains t, the number of test cases. Each test case begins with 3 <= n <= 1000 - the number of words in the dictionary. n distinct dictionary words follow; each word is a string of between 1 and 20 lowercase letters on a line by itself.

Output

For each test case, output a line giving the lexicographically least compound catenym that contains each dictionary word exactly once. Output "***" if there is no solution.

Sample Input

2
6
aloha
arachnid
dog
gopher
rat
tiger
3
oak
maple
elm

Sample Output

aloha.arachnid.dog.gopher.rat.tiger
***


先判断是否存在欧拉路径,然后再按照字典序输出欧拉路径,想写个非递归的深搜,可惜失败了

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #include<string>
  5 #include<algorithm>
  6 #include<climits>
  7 #define MAXE 1010
  8 #define MAXP 28
  9 using namespace std;
 10 struct Edge
 11 {
 12     int s,t,next;
 13     char str[25];
 14 }edge[MAXE];
 15 int head[MAXE];
 16 int degree[MAXP];
 17 int fa[MAXP];
 18 int stack[MAXE];
 19 bool used[MAXP];
 20 bool sign[MAXE];
 21 bool cur[MAXE][MAXE];
 22 int start;
 23 int n;
 24 int top;
 25 bool cmp(Edge a,Edge b)
 26 {
 27     return strcmp(a.str,b.str)>0;
 28 }
 29 void add(int s,int t,int ent)
 30 {
 31     edge[ent].s=s;
 32     edge[ent].t=t;
 33     edge[ent].next=head[s];
 34     head[s]=ent;
 35 }
 36 int find(int x)
 37 {
 38     int temp=x,i;
 39     while(fa[x]!=x)
 40         x=fa[x];
 41     while(fa[temp]!=x)
 42     {
 43         i=fa[temp];
 44         fa[temp]=x;
 45         temp=i;
 46     }
 47     return x;
 48 }
 49 bool oula()
 50 {
 51     int temp=0,temp2=0;
 52     start=edge[n].s;
 53     for(int i=1;i<=26;i++)
 54     {
 55         if(used[i])
 56         {
 57             if(fa[i]==i)temp++;
 58             if(degree[i])
 59             {
 60                 if(degree[i]>1||degree[i]<-1)return false;
 61                 if(degree[i]==-1)start=i;
 62                 temp2++;
 63             }
 64         }
 65     }
 66     if(temp!=1)return false;
 67     if(temp2&&temp2!=2)return false;
 68     return true;
 69 }
 70 void dfs(int s)
 71 {
 72     for(int i=head[s];i!=-1;i=edge[i].next)
 73     {
 74         if(!sign[i])
 75         {
 76             sign[i]=true;
 77             dfs(edge[i].t);
 78             stack[++top]=i;
 79         }
 80     }
 81     /*while(1)
 82     {
 83         if(top==n)break;
 84         int temp=head[s];
 85         for(int i=head[s];i!=-1;temp=i=edge[i].next)
 86         {
 87             if(!sign[i]&&!cur[stack[top]][i])break;
 88         }
 89         if(temp==-1)
 90         {
 91             cur[stack[top-1]][stack[top]]=true;
 92             sign[stack[top]]=false;
 93             sign[stack[top-1]]=false;
 94             s=edge[stack[--top]].s;
 95         }
 96         else
 97         {
 98             stack[++top]=temp;
 99             s=edge[temp].t;
100             sign[temp]=true;
101         }
102     }*/
103 }
104 int main()
105 {
106     int cas;
107     scanf("%d",&cas);
108     while(cas--)
109     {
110         memset(head,-1,sizeof(head));
111         memset(sign,false,sizeof(sign));
112         memset(used,false,sizeof(used));
113         memset(cur,false,sizeof(cur));
114         memset(degree,0,sizeof(degree));
115         scanf("%d",&n);
116         for(int i=1;i<=n;i++)
117             scanf("%s",edge[i].str);
118         sort(edge+1,edge+1+n,cmp);
119         for(int i=1;i<=26;i++)
120             fa[i]=i;
121         for(int i=1;i<=n;i++)
122         {
123             int s=edge[i].str[0]-'a'+1,t=edge[i].str[strlen(edge[i].str)-1]-'a'+1;
124             add(s,t,i);
125             fa[find(t)]=find(s);
126             degree[s]--;
127             degree[t]++;
128             used[s]=true;
129             used[t]=true;
130         }
131         if(!oula())
132         {
133             printf("***\n");
134         }
135         else
136         {
137             top=0;
138             dfs(start);
139             /*for(int i=1;i<=top-1;i++)
140                 printf("%s.",edge[stack[i]].str);
141             printf("%s\n",edge[stack[top]].str);*/
142             for(int i=top;i>=2;i--)
143                 printf("%s.",edge[stack[i]].str);
144             printf("%s\n",edge[stack[1]].str);
145         }
146     }
147     return 0;
148 }
View Code