您的位置:首页 > 其它

POJ - 2337 Catenyms(单词拼接)欧拉通路

2016-07-21 17:54 337 查看
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
***


分析:

欧拉路径和欧拉回路

欧拉路径:从某结点出发一笔画成所经过的路线叫做欧拉路径。

欧拉回路:在欧拉路径的基础上又回到起点。

a、凡是由偶点组成的连通图,一定可以一笔画成。画时可以把任一偶点为起点,最后一定能以这个点为

终点画完此图。   

b、凡是只有两个奇点的连通图(其余都为偶点),一定可以一笔画成。画时必须把一个奇点为起点,另

一个奇点终点。  

c、其他情况的图都不能一笔画出。(有偶数个奇点除以2便可算出此图需几笔画成。)

欧拉回路和欧拉路径的判断

欧拉回路:

无向图:每个顶点的度数都是偶数,则存在欧拉回路。

有向图:每个顶点的入度都等于出度,则存在欧拉回路。

欧拉路径:

无向图:当且仅当该图所有顶点的度数为偶数 或者 除了两个度数为奇数外其余的全是偶数。

有向图:当且仅当该图所有顶点 出度=入度 或者 一个顶点 出度=入度+1,另一个顶点 入度=出度+1,其他顶点 出度=入度。
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
struct node
{
char s[30];
int start,end;

} a[1001];
int f[1001];
int cmp(node p,node q)
{
return strcmp(p.s,q.s)<0;
}
int in[1001],out[1001],order[1001],m;
int fun()
{
int x1,x2,ans=0,i;
x1=x2=0;
for(i=0; i<26; i++)
{
if(abs(in[i]-out[i])>=2)
return -1;
else if((in[i]-out[i])==1)//统计入度大于出度的顶点个数
x1++;
else if(in[i]-out[i]==-1)//统计出度大于入度的顶点个数
{
x2++;
ans=i;//环路的起点
}
}
if(x1>1||x2>1)
return -1;
else if(x1==0)
{
for(i=0; i<26; i++)
if(out[i])
return i;
}
else
return ans;
}
int dfs(int st,int cnt)//深搜判断是否连通
{
int i;
if(cnt==m)
return 1;
for(i=0; i<m; i++)
{
if(a[i].start<st||f[i])
continue;
else if(a[i].start>st)
return 0;
f[i]=1;
order[cnt]=i;
if(dfs(a[i].end,cnt+1))
return 1;
f[i]=0;
}
return 0;
}
int main()
{
int n,slen,i,t;
scanf("%d",&n);
while(n--)
{
memset(f,0,sizeof(f));
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
scanf("%d",&m);
for(i=0; i<m; i++)
{
scanf("%s",a[i].s);
slen=strlen(a[i].s);
a[i].start=a[i].s[0]-'a';
a[i].end=a[i].s[slen-1]-'a';
in[a[i].end]++;//尾字符作为入度
out[a[i].start]++;//首字母作为出度
}
t=fun();//判断是否能形成欧拉路径
sort(a,a+m,cmp);
if(t==-1||!dfs(t,0))
{
printf("***\n");
continue;
}
printf("%s",a[order[0]].s);
for(i=1; i<m; i++)
printf(".%s",a[order[i]].s);
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: