这道题是,欧拉路和并查集结合起来的一道很恶心的题,最主要的难点在于,将这个模型抽象为欧拉路,已经应该用怎么样的存储方式。还有代码长了过后,变量的赋值一定要特别小心啊,我就是在一个地方把begin = i写成了begin - a; 于是就浪费了我好几个小时呢
Catenyms
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 5806 | Accepted: 1503 |
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
源代码:
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
#define MAXN 1010
#define len 30
using namespace std;
char str[MAXN][len];
char str1[MAXN][len];
int father[len], n, changdu;
struct orer{
int from, to, visit;
}oulaa[MAXN];
int cmp(const void *a, const void *b){
return strcmp((char *)a, (char *)b);
}
int find(int x){
int i,j;
i = x;
while(x != father[x]) x = father[x];
while(i != x){//完成状态压缩
j = father[i];
father[i] = x;
i = j;
}
return x;
}
void merge(int a, int b){
int x = find(a);
int y = find(b);
father[x] = y;
}
void eurlar(int start,int size){
for(int i=1;i<=size;i++)
{
if(!oulaa[i].visit && oulaa[i].from==start)
{
oulaa[i].visit = 1;
eurlar(oulaa[i].to, size);
strcpy(str1[++changdu],str[i]);
}
}
}
int main(){
int t, in_out,a, b,begin, flag, in[len], out[len], used[len];
scanf("%d", &t);
while(t--){
//printf("t : %d\n", t);
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
memset(used, 0, sizeof(used));
scanf("%d", &n);
if(n<3){printf("***");printf("\n");continue;}
in_out = 0;
for(int i = 1; i <= n; i++){
scanf("%s", str[i]);
}
for(int i = 1; i <= 26; i++){
father[i] = i;
}
qsort(str+1, n, sizeof(str[0]), cmp);
for(int i = 1; i <= n; i++){
a = str[i][0] - 'a' + 1;
b = str[i][strlen(str[i]) - 1] - 'a' + 1;
oulaa[i].from = a;
oulaa[i].to = b;
oulaa[i].visit = 0;
in[b]++;
out[a]++;
merge(a,b);
used[a] = 1;
used[b] = 1;
}
/*
for(int i = 1; i <= 26; i++){
if(in[i] != out[i])
in_out++;
}
if(in_out > 2){
printf("***\n");
continue;
}*/
a = 0;
b = 0;
for(int i = 1; i<= 26; i++){
if(father[i] == i && used[i])
b++;
}
if(b > 1){
printf("***\n");
continue;
}
a = 0,b = 0,flag = 0;
for(int i = 1; i <= 26; i++){
if(in[i] == out[i]) continue;
else if(in[i] - 1 == out[i]) a++;
else if(in[i] + 1 == out[i]) b++;
else {
flag = 1;
break;
}
}
if(flag == 1 || a > 1 || b > 1 || a != b){
printf("***\n");
continue;
}
begin = 1;
changdu = 0;
if(a == 1){
for(int i = 1; i <= n;i++){
if(out[oulaa[i].from] - in[oulaa[i].from] == 1){
begin = i;
break;
}
}
}
eurlar(oulaa[begin].from, n);
for(int i = changdu; i > 1; i--){
printf("%s.", str1[i]);
}
printf("%s\n", str1[1]);
}
return 0;
}