POJ2337 Catenyms(欧拉通路的求解)

                                                           Catenyms
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 11526   Accepted: 2993

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
***
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <vector>
#include<functional>
#define mod 1000000007
#define inf 0x3f3f3f3f
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
const int N=1005;
const int M=150005;
ll power(ll a,int b,ll c) {
    ll ans=1;
    while(b) {
        if(b%2==1) {
            ans=(ans*a)%c;
            b--;
        }
        b/=2;
        a=a*a%c;
    }
    return ans;
}
struct Word { int l; char s[21]; };
struct Edge { int st, ed; bool del; };

Word word[1002];
Edge edge[1002];
int in[30], out[30];
int stk[1002], father[30];
bool mark[30];
int E, top;

int cmp ( const void* a, const void* b )
{
    return strcmp( ((Word*)a)->s, ((Word*)b)->s );
}

int find_set ( int x )
{
    if ( father[x] != x )
        father[x] = find_set ( father[x] );
    return father[x];
}

bool judge ()
{
    int t = 0;
    for ( int i = 0; i < 26; i++ )
        if ( mark[i] && father[i] == i ) t++;
    return t == 1;
}

void find_path ( int u )
{
    for ( int i = 0; i < E; i++ )
    {
        if ( ! edge[i].del && edge[i].st == u )
        {
            edge[i].del = true;
            find_path ( edge[i].ed );
            stk[top++] = i;
        }
    }
}

int main()
{
    int cs;
    scanf("%d",&cs);
    while ( cs-- )
    {
        scanf("%d",&E);
        int u, v, c1, c2, start, i;

        for ( i = 0; i < 26; i++ )
        {
            in[i] = out[i] = 0;
            father[i] = i;
            mark[i] = false;
        }

        for ( i = 0; i < E; i++ )
        {
            scanf("%s",word[i].s);
            word[i].l = strlen(word[i].s);
        }

        qsort(word, E, sizeof(word[0]), cmp);

        for ( i = 0; i < E; i++ )
        {
            u = word[i].s[0] - 'a';
            v = word[i].s[word[i].l-1] - 'a';
            edge[i].st = u;
            edge[i].ed = v;
            edge[i].del = false;
            mark[u] = mark[v] = true;
            out[u]++; in[v]++;
            u = find_set ( u );
            v = find_set ( v );
            if ( u != v ) father[v] = u;
        }

        c1 = c2 = 0;
        start = edge[0].st;
        for ( i = 0; i < 26; i++ )
        {
            if ( in[i] == out[i] ) continue;
            else if ( in[i] - 1 == out[i] ) c1++;
            else if ( out[i] - 1 == in[i] ) { c2++; start = i; }
            else break;
        }

        if ( i == 26 && ((c1 == c2 && c1 == 1) || (c1 == c2 && c1 == 0)) && judge() )
        {
            top = 0;
            find_path ( start );
            for ( i = top - 1; i > 0; i-- )
                printf("%s.",word[stk[i]].s);
            printf("%s\n",word[stk[0]].s);
        }
        else printf("***\n");
    }
    //system("pause");
    return 0;
}
View Code

 

posted @ 2016-08-25 16:40  贱人方  阅读(268)  评论(0)    收藏  举报