现在的位置: 首页 > 综合 > 正文

POJ2337—Catenyms

2019年02月16日 ⁄ 综合 ⁄ 共 2891字 ⁄ 字号 评论关闭
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:
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");
		}
	}
}

抱歉!评论已关闭.