码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 2337 Catenyms (有向图欧拉通路)

时间:2015-01-31 23:17:35      阅读:234      评论:0      收藏:0      [点我收藏+]

标签:poj   欧拉通路   

Catenyms


Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 9914   Accepted: 2588

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

题目链接:http://poj.org/problem?id=2337

题目大意:t组样例,每组n个字符串,如果一个字符串的尾字符和另一个的头字符相同则可以连接,问能不能将这n个都连接起来,能的话按要求输出结果,不能输出***

题目分析:本题构图思路很简单,一个字符串的第一个字符和最后一个字符为结点,字符串本身为边,因为本题没说连通,我们要先用并查集判连通,若根不唯一则说明不连通,接着就是看点的出入度,某结点出入度相差大于1或相差等于1的多于2个则不存在欧拉通路,否则若存在欧拉通路,则把出度比入度大1的结点当起点,若存在欧拉回路,则取字典序最小的做为起点。本体要求最后答案的字典序最小,因此我们再判断前要先对字符串由小到大排序,至于找通路,直接DFS,本题边很少,所以可以直接通过边来找

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct EDGE
{
    char s[25];
    int x, y; 
}e[1005];
bool has[30], vis[1005];
int in[30], out[30], fa[30], ans[1005];
int n, st, len;

bool cmp(EDGE a, EDGE b)
{
    return strcmp(a.s, b.s) < 0;
}

int abs(int x)
{
    return x > 0 ? x : -x;
}

int change(char ch)
{
    return int(ch - 'a' + 1);
}

void UF_set()
{
    for(int i = 0; i < 200; i++)
        fa[i] = i;
}

int Find(int x)
{
    return fa[x] == x ? x : fa[x] = Find(fa[x]);
}

void Union(int a, int b)
{
    int r1 = Find(a);
    int r2 = Find(b);
    if(r1 != r2)
        fa[r1] = r2;
}

bool exist()
{
    int t = -1;
    for(int i = 1; i <= 26; i++)
    {
        if(has[i])
        {
            if(t == -1)
                t = Find(i);
            if(t != Find(i))
                return false;
        }
    }
    int sum = 0, tmp = 100;
    for(int i = 1; i <= 26; i++)
    {
        if(has[i])
        {
            tmp = min(tmp, i);
            if(in[i] != out[i])
            {
                if(abs(in[i] - out[i]) > 1)
                    return false;
                if(out[i] > in[i])
                    st = i;
                sum ++;
            }
        }
    }
    if(sum > 2)
        return false;
    if(sum == 0)
        st = tmp;
    return true;
}

void DFS(int now)
{
    for(int i = 0; i < n; i++)
    {
        if(!vis[i] && e[i].x == now)
        {
            vis[i] = true;
            DFS(e[i].y);
            ans[len++] = i;
        }
    }
}

int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        st = 0;
        UF_set();
        memset(has, false, sizeof(has));
        memset(in, 0, sizeof(in));
        memset(out, 0, sizeof(out));
        scanf("%d", &n);
        for(int i = 0; i < n; i++)
        {
            scanf("%s", e[i].s);
            e[i].x = change(e[i].s[0]);
            e[i].y = change(e[i].s[(int)strlen(e[i].s) - 1]);
            has[e[i].x] = true;
            has[e[i].y] = true;
            in[e[i].y] ++;
            out[e[i].x] ++;
            Union(e[i].x, e[i].y);
        }
        sort(e, e + n, cmp);
        if(exist())
        {
            len = 0;
            memset(vis, false, sizeof(vis));
            DFS(st);
            for(int i = len - 1; i > 0; i--)
                printf("%s.", e[ans[i]].s);
            printf("%s\n", e[ans[0]].s);
        }
        else
            printf("***\n");
    }
}


POJ 2337 Catenyms (有向图欧拉通路)

标签:poj   欧拉通路   

原文地址:http://blog.csdn.net/tc_to_top/article/details/43347537

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!