首页 > 其他 > 详细

Catenyms+欧拉回路/欧拉路+并查集+POJ

时间:2014-08-05 19:36:30      阅读:315      评论:0      收藏:0      [点我收藏+]
Catenyms
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 9617   Accepted: 2524

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
***
解决方案:首先建立一个图的模型:用单词的首尾字母做节点,用单词做边。这些单词能连成一串,必须:1)能形成欧拉路或欧拉回路;2)要能构成一个连通图。先是判断是欧拉回路/欧拉路:记录每个顶点的出度与入度,若有一个点出度大入度1,一个点入度大出度1,其余出度等于入度,则为欧拉路;若每个店的出度与入度都相等,则为欧拉回路。然后判断是否为联通的,可用并查集来判断,这个就不用说了。然后是怎么建图的问题,这个最好用头插法建图,记录每个顶点所连得边及终点。再则就是输出要字典序的问题,可以这样子,先对单词进行排序,然后按照排好顺序的单词建图,是要从小到大,还是从大到小排呢。若是从小到大,由于是头插法建图,那么每次遍历边的时候,这个按字典序从大到小来遍历的,所以,我们应该从大到小排序。还有就是起点的问题:若是欧拉路,则出度比入度大1的那个点做起点,若是欧拉回路,字典序最小的点做起点。
code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#define MMAX 1003
using namespace std;
string word[MMAX];
int fa[27],in[27],out[27];
int Map[27][27];
bool vise[MMAX];
bool cmp(string a,string b)
{
    return a>b;
}
stack<string>S;
int N,k;
int head[27];
struct node
{
    int from,to;
    string word;
    int next;
} E[MMAX];
void add(int from,int to,string word)
{
    E[k].from=from;
    E[k].to=to;
    E[k].word=word;
    E[k].next=head[from];
    head[from]=k++;
}
bool vis[27];
int faset(int x)
{

    return x!=fa[x]?fa[x]=faset(fa[x]):x;
}
int C(char c)
{
    return int(c-'a');
}
void dfs(int v)
{
    for(int i=head[v]; i!=-1; i=E[i].next)
    {
        if(!vise[i])
        {
            vise[i]=true;
            dfs(E[i].to);
            S.push(E[i].word);

        }
    }

}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        memset(head,-1,sizeof(head));
        memset(vis,false,sizeof(vis));
        memset(in,0,sizeof(in));
        memset(out,0,sizeof(out));
        memset(Map,0,sizeof(Map));
        memset(vise,false,sizeof(vise));
        while(!S.empty())S.pop();
        for(int i=0; i<26; i++)
        {
            fa[i]=i;
        }
        scanf("%d",&N);
        for(int i=0; i<N; i++)
        {
            cin>>word[i];
        }
        sort(word,word+N,cmp);
        k=0;
        for(int i=0; i<N; i++)
        {
            int len=word[i].length();
            int st=C(word[i][0]),en=C(word[i][len-1]);
            add(st,en,word[i]);
            int x=faset(st),y=faset(en);
            vis[st]=true,vis[en]=true;
            if(x!=y)
            {
                fa[x]=y;
            }
            in[en]++,out[st]++;
        }
        bool flag=true;
        int pre=faset(C(word[0][0]));
        for(int i=0; i<26; i++)
        {
            if(vis[i])
            {
                if(pre!=faset(i))
                {
                    flag=false;
                    break;
                }
            }
        }
        int st,cst=0,cen=0,cnt=0;
        st=C(word[N-1][0]);
        for(int i=0; i<26; i++)
        {
            if(in[i]!=out[i])
            {
                if(abs(in[i]-out[i])>1)
                {
                    flag=false;
                    break;
                }
                if(in[i]+1==out[i]) cst++,st=i;

                if(out[i]+1==in[i]) cen++;
                cnt++;
            }
        }
        if((cst==1&&cen==1)||!cnt) ;
        else flag=false;
        if(flag)
        {
            dfs(st);
            while(!S.empty())
            {
                string temp=S.top();
                S.pop();
                cout<<temp<<".";
                if(S.size()==1) break;
            }
            cout<<S.top()<<endl;
            S.pop();
        }
        else
        {
            printf("***\n");
        }
    }
    return 0;
}

Catenyms+欧拉回路/欧拉路+并查集+POJ,布布扣,bubuko.com

Catenyms+欧拉回路/欧拉路+并查集+POJ

原文:http://blog.csdn.net/u012870383/article/details/38386701

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!