Catenyms
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 9454 | Accepted: 2486 |
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:
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.
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 ***分析:
题目的意思是给出来n个单词,看看是否能连成一条单词串,要把每个单词都搜索一遍很容易想到是欧拉通路,以每个单词的首字母和末字母为定点建边,权值状态为该单词,编号a,b,c……为1,2,3,……
首先用并查集判断改图是否是连通图不是的话输出***
然后判断该图是欧拉通路还是欧拉回路,若是欧拉回路的话从最小的点开始深搜,若是欧拉通路的话从出度比入度大一的点开始深搜,否则输出***
此题还让输出结果保证字典序最小,让单词按照逆序快排即可
定义:
1.无向图存在欧拉回路的充要条件:
连通且没有奇度顶点。
2.无向图存在欧拉路径的充要条件:
连通且奇度顶点个数为2。
3.有向图存在欧拉路径的充要条件:
基图连通且存在某顶点入度比出度大1,另一顶点出度比入度大1,其余顶点入度等于出
4.有向图存在欧拉回路的充要条件:
基图连通且所有顶点入度等于出度。
程序:
#include"stdio.h"
#include"string.h"
#include"queue"
#include"stack"
#include"iostream"
#include"string"
#include"map"
#include"stdlib.h"
#define inf 99999999
#define M 10009
using namespace std;
struct st
{
int u,v,w,next,vis;
}edge[M];
int head[M],use[M],s[M],out[M],in[M];
int t,num;
int f[M];
int finde(int x)
{
if(x!=f[x])
f[x]=finde(f[x]);
return f[x];
}
void make(int a,int b)
{
f[finde(a)]=finde(b);
}
int cmp(const void *a,const void *b)
{
return strcmp((char *)b,(char *)a);
}
void init()
{
t=0;
memset(head,-1,sizeof(head));
memset(out,0,sizeof(out));
memset(in,0,sizeof(in));
memset(use,0,sizeof(use));
memset(edge,0,sizeof(edge));
for(int i=0;i<=100;i++)
f[i]=i;
}
void add(int u,int v,int w)
{
edge[t].u=u;
edge[t].v=v;
edge[t].w=w;
edge[t].next=head[u];
head[u]=t++;
}
void DFS(int u)
{
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(!edge[i].vis)
{
edge[i].vis=1;
DFS(v);
s[num++]=edge[i].w;
}
}
}
char ch[M][111];
int main()
{
int T,i,a,b,n,m;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%s",ch[i]);
qsort(ch,n,sizeof(ch[0]),cmp);
init();
for(i=0;i<n;i++)
{
m=strlen(ch[i]);
a=ch[i][0]-'a'+1;
b=ch[i][m-1]-'a'+1;
use[a]=1;
use[b]=1;
make(a,b);
add(a,b,i);
out[a]++;
in[b]++;
}
int tmp=finde(a);
int flag=0;
for(i=1;i<=26;i++)
{
if(use[i]&&finde(i)!=tmp)
flag++;
}
if(flag)
{
printf("***\n");continue;
}
int f1=0,f2=0,ff=0;
for(i=1;i<=26;i++)
{
if(!use[i])
continue;
if(out[i]-in[i]>1||in[i]-out[i]>1)
ff++;
if(out[i]==in[i]+1)
f1++;
if(out[i]+1==in[i])
f2++;
}
if(f1==0&&f2==0&&ff==0)
{
num=0;
for(i=1;i<=26;i++)
{
if(use[i])
{
DFS(i);
break;
}
}
for(i=num-1;i>=0;i--)
{
if(i==num-1)
printf("%s",ch[s[i]]);
else
printf(".%s",ch[s[i]]);
}
printf("\n");
}
else if(f1==1&&f2==1&&ff==0)
{
num=0;
for(i=1;i<=26;i++)
{
if(use[i]&&in[i]+1==out[i])
{
DFS(i);
break;
}
}
for(i=num-1;i>=0;i--)
{
if(i==num-1)
printf("%s",ch[s[i]]);
else
printf(".%s",ch[s[i]]);
}
printf("\n");
}
else
printf("***\n");
}
}