poj 2337(单向欧拉路的判断以及输出)

Catenyms

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 11648   Accepted: 3036

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,终点:入度-出度=1,其它点:入度==出度

有向欧拉回路:所有点:入度==出度

还要利用并查集判断一下这个图是否只有一个连通分量.

然后将所有的边按照字典序排序,找到起点,进行DFS(Edge &e = edge[u][i] 这里检查了半天,一点要记得是地址啊...),即可得到答案.

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <vector>
#include <stack>
using namespace std;
const int N = 2222;
char str[100];
struct Edge{
    char str[100];
    int to,del;
};

typedef vector <Edge> vec;
stack <string> ans;
vec edge[N];
int in[N],out[N],father[N];
bool vis[N],mark[30];
int n;
void init(){
    memset(in,0,sizeof(in));
    memset(out,0,sizeof(out));
    memset(vis,false,sizeof(vis));
    for(int i=1;i<=30;i++){
        mark[i] = false;
        edge[i].clear();
        father[i] = i;
    }
}
int _find(int x){
    return x==father[x]?x:father[x] = _find(father[x]);
}

void dfs(int u){
    for(int i=0;i<edge[u].size();i++){
        Edge &e = edge[u][i];  ///这里要取地址
        int v = e.to;
        if(!e.del){
            e.del = 1;
            dfs(v);
            ans.push(e.str);
        }
    }
}
bool cmp(Edge a,Edge b){
    return strcmp(a.str,b.str)<0;
}
int main()
{
    int tcase;
    scanf("%d",&tcase);
    while(tcase--){
        init();
        scanf("%d",&n);
        int S = N;
        for(int i=1;i<=n;i++){
            scanf("%s",str);
            int s = str[0]-‘a‘+1;
            int t = str[strlen(str)-1]-‘a‘+1;
            Edge e;
            e.del = 0;
            strcpy(e.str,str);
            e.to = t;
            edge[s].push_back(e);
            in[t]++;
            out[s]++;
            mark[t] = mark[s] = 1;
            int u = _find(s);
            int v = _find(t);
            if(u!=v) father[u] = v;
            S = min(S,min(s,t));
        }
        int num1 = 0,num2 = 0,num3 = 0,num4 = 0;
        for(int i=1;i<=26;i++){
            if(mark[i]==1&&father[i]==i) num4++;
            if(out[i]-in[i]==1){
                S = i;
                num1++;
            }
            else if(in[i]-out[i]==1){
                num2++;
            }else if(in[i]-out[i]!=0){
                num3++;
            }
            if(!edge[i].empty())
            sort(edge[i].begin(),edge[i].end(),cmp);
        }
        if(num3||!(num1==1&&num2==1)&&!(num1==0&&num2==0)||num4>1){
            printf("***\n");
            continue;
        }
       dfs(S);
       int flag = 0;
       while(!ans.empty()){
            if(flag) printf(".");
            cout<<ans.top();
            flag = 1;
            ans.pop();
        }
        printf("\n");
    }
}
时间: 2024-08-07 04:33:03

poj 2337(单向欧拉路的判断以及输出)的相关文章

POJ 2513 Colored Sticks 欧拉路的判断+字典树

题目链接: poj2513 题意: 给定一捆木棍.每根木棍的每个端点涂有某种颜色.问:是否能将这些棍子首尾相连,排成 一条直线,且相邻两根棍子的连接处端点的颜色一样. 输入描述: 输入文件中包含若干行,每行为两个单词,用空格隔开,表示一根棍子两个端点的颜色.表 示颜色的单词由小写字母组成,长度不超过10 个字符.木棍的数目不超过250000. 输出描述: 如果木棍能按照题目的要求排成一条直线,输出"Possible",否则输出"Impossible". 解题思路:

POJ 2337 Catenyms 欧拉通路

题目链接:点击打开链接 题意: 把输入的n个由小写字母构成的字符串连成字典序最小的一句话,使得所有字符串都恰好出现一次且相邻两个字符串相邻的字母相同 思路: 比如abcd,我们认为是这样一条边:a->d 所以我们在a->d间建一条边. 1.如:abcd, dfgh, 那么得到的边就是 a->d, d->h. 而题目的目标是每个字符串恰好用一次,即每条边恰好用一次.也就是找一条欧拉通路 2.我们只需要关心字符串的首尾2个字母,所以我们认为图里只有26个节点. 3.判断欧拉通路是否存在

poj 1392 构造欧拉路遍历所有可能

http://poj.org/problem?id=1392 其实就是构造一个最小的数字序列,使得每n位都是一个数字,而且不重复 比如n=2  序列是00110   两个两个看就是00--0  01---1 11--3 10--2 先总结知识: 1.k进制下,这样的序列长度是k^n+n-1. 首先第一个数长度是n,后面k^n -1个数,每个数只需要增加一位就行了,所以是k^n+n-1. 2.最小 我开始的时候按回溯写,WA,然后把vis[ s ]=0注释掉 AC,不是很明白为什么,再做几题作总结

poj 2337 &amp;&amp; zoj 1919 欧拉回路+连通性判断

题目要求按字典序排列,而且可能有重边 所以一开始就将数组从大到小排列,那么我将字符串加入链表时就会令小的不断前移,大的被挤到后面 这里有一点问题就是我一开始使用的是qsort: int cmp(const void *s1 , const void *s2){    return strcmp((char*)s1 , (char*)s2)<0;} qsort(str , n , sizeof(str[0]) , cmp) poj一直wa,试了发zoj却过了,可能是编译器原因吧,然后将字符串放入了

欧拉路&amp;&amp;欧拉回路 概念及其练习

欧拉路: 如果给定无孤立结点图G,若存在一条路,经过图中每边一次且仅一次,这条路称为欧拉路: 如果给定无孤立结点图G,若存在一条回路,经过图中每边一次且仅一次,那么该回路称为欧拉回路. 存在欧拉回路的图,称为欧拉图. 一. 对于无向图G,具有一条欧拉路,当且仅当G是连通的,且有零个或两个奇数度结点. 且有零个奇数度结点,存在欧拉回路:有两个奇数度结点,存在欧拉路. 判断无向图G是否连通,可以从任意结点出发,进行深度优先遍历,如果可以遍历到所有点,也可以用并查集,判断根节点的个数, 说明,图G连通

图论--欧拉路,欧拉回路(小结)

在题目中在慢慢细说概念 1.HDU - 3018 Ant Trip 题目大意:又N个村庄,M条道路,问需要走几次才能将所有的路遍历 解题思路:这题问的是有关欧拉路的判定 欧拉路就是每条边只能走一次,且要遍历所有的边,简单的说就是一笔画(图连通) 这道题是无向图的欧拉路,无向图的欧拉路的判定:所有点的度数都是偶数度,或者只有两个点的度是奇数度,且图要是连通图 知道欧拉路是什么后,这题就比较好做了,第一件事就是找到有几个连通块,然后再判断一下每个连通块需要几笔才能完成就好了 #include <cs

HDU5883 The Best Path(并查集+欧拉路)

题意: n个点m条边,问m条边构成的是否为欧拉路. 是的话输出路径上所有点的异或和,每个点经过几次异或几次. 思路: 先用并查集判断是否连通,然后如果是欧拉路的话有两种情况 如果奇数度节点有2个,就枚举这两个点做起点,选大的 如果都为偶数度节点,就枚举n个起点,选大的 /* *********************************************** Author :devil ************************************************ *

POJ 2337 &amp;&amp; ZOJ 1919--Catenyms 【有向图 &amp;&amp; 欧拉路判断 &amp;&amp; 欧拉路径】

Catenyms Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10427   Accepted: 2726 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

POJ 2337 欧拉路

Catenyms Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11214   Accepted: 2908 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