Catenyms
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 9887 | Accepted: 2583 |
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 ***
Source
Waterloo local 2003.01.25
有向图欧拉通路
有向图欧拉通路
/*************************************************************************
> File Name: poj2337.cpp
> Author: ALex
> Mail: zchao1995@gmail.com
> Created Time: 2015年01月29日 星期四 13时15分00秒
************************************************************************/
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const double eps = 1e-15;
typedef long long LL;
typedef pair <int, int> PLL;
const int N = 30;
int in[N];
int out[N];
int father[N];
bool vis[N];
string str[1010];
vector <PLL> edge[N];
stack <int> st;
int find (int x)
{
if (father[x] == -1)
{
return x;
}
return father[x] = find (father[x]);
}
void dfs (int u)
{
while (!edge[u].empty())
{
PLL tmp = edge[u].back();
int v = tmp.second;
edge[u].pop_back();
dfs (v);
st.push(tmp.first);
}
}
int main ()
{
int t;
scanf("%d", &t);
while (t--)
{
int n;
scanf("%d", &n);
for (int i = 0; i < N; ++i)
{
edge[i].clear();
}
for (int i = 0; i < n; ++i)
{
cin >> str[i];
}
sort (str, str + n);
memset (father, -1, sizeof(father));
memset (in, 0, sizeof(in));
memset (out, 0, sizeof(out));
memset (vis, 0, sizeof(vis));
while (!st.empty())
{
st.pop();
}
int start = inf;
for (int i = n - 1; i >= 0; --i)
{
int u = str[i][0] - 'a';
int len = str[i].length();
int v = str[i][len - 1] - 'a';
++out[u];
++in[v];
edge[u].push_back (make_pair(i, v));
start = min (start, min(u, v));
int uu = find (u);
int vv = find (v);
vis[u] = vis[v] = 1;
if (uu != vv)
{
father[uu] = vv;
}
}
int block = 0;
for (int i = 0; i < N; ++i)
{
if (vis[i])
{
if (father[i] == -1)
{
++block;
}
}
}
if (block > 1)
{
printf("***\n");
continue;
}
int c1 = 0, c2 = 0;
bool flag = false;
for (int i = 0; i < N; ++i)
{
if (vis[i])
{
if (out[i] - in[i] == 1)
{
start = i;
++c1;
}
else if (out[i] - in[i] == -1)
{
++c2;
}
else if (out[i] != in[i])
{
flag = true;
break;
}
}
}
if (flag || !((c1 == 0 && c2 == 0) || (c1 == 1 && c2 == 1)))
{
printf("***\n");
}
else
{
dfs (start);
while (!st.empty())
{
int u = st.top();
st.pop();
cout << str[u];
if (!st.empty())
{
printf(".");
}
}
printf("\n");
}
}
}