poj 2337 有向图输出欧拉路径

Catenyms

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 10186   Accepted: 2650

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 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #include<string>
  5 #include<algorithm>
  6 #include<climits>
  7 #define MAXE 1010
  8 #define MAXP 28
  9 using namespace std;
 10 struct Edge
 11 {
 12     int s,t,next;
 13     char str[25];
 14 }edge[MAXE];
 15 int head[MAXE];
 16 int degree[MAXP];
 17 int fa[MAXP];
 18 int stack[MAXE];
 19 bool used[MAXP];
 20 bool sign[MAXE];
 21 bool cur[MAXE][MAXE];
 22 int start;
 23 int n;
 24 int top;
 25 bool cmp(Edge a,Edge b)
 26 {
 27     return strcmp(a.str,b.str)>0;
 28 }
 29 void add(int s,int t,int ent)
 30 {
 31     edge[ent].s=s;
 32     edge[ent].t=t;
 33     edge[ent].next=head[s];
 34     head[s]=ent;
 35 }
 36 int find(int x)
 37 {
 38     int temp=x,i;
 39     while(fa[x]!=x)
 40         x=fa[x];
 41     while(fa[temp]!=x)
 42     {
 43         i=fa[temp];
 44         fa[temp]=x;
 45         temp=i;
 46     }
 47     return x;
 48 }
 49 bool oula()
 50 {
 51     int temp=0,temp2=0;
 52     start=edge[n].s;
 53     for(int i=1;i<=26;i++)
 54     {
 55         if(used[i])
 56         {
 57             if(fa[i]==i)temp++;
 58             if(degree[i])
 59             {
 60                 if(degree[i]>1||degree[i]<-1)return false;
 61                 if(degree[i]==-1)start=i;
 62                 temp2++;
 63             }
 64         }
 65     }
 66     if(temp!=1)return false;
 67     if(temp2&&temp2!=2)return false;
 68     return true;
 69 }
 70 void dfs(int s)
 71 {
 72     for(int i=head[s];i!=-1;i=edge[i].next)
 73     {
 74         if(!sign[i])
 75         {
 76             sign[i]=true;
 77             dfs(edge[i].t);
 78             stack[++top]=i;
 79         }
 80     }
 81     /*while(1)
 82     {
 83         if(top==n)break;
 84         int temp=head[s];
 85         for(int i=head[s];i!=-1;temp=i=edge[i].next)
 86         {
 87             if(!sign[i]&&!cur[stack[top]][i])break;
 88         }
 89         if(temp==-1)
 90         {
 91             cur[stack[top-1]][stack[top]]=true;
 92             sign[stack[top]]=false;
 93             sign[stack[top-1]]=false;
 94             s=edge[stack[--top]].s;
 95         }
 96         else
 97         {
 98             stack[++top]=temp;
 99             s=edge[temp].t;
100             sign[temp]=true;
101         }
102     }*/
103 }
104 int main()
105 {
106     int cas;
107     scanf("%d",&cas);
108     while(cas--)
109     {
110         memset(head,-1,sizeof(head));
111         memset(sign,false,sizeof(sign));
112         memset(used,false,sizeof(used));
113         memset(cur,false,sizeof(cur));
114         memset(degree,0,sizeof(degree));
115         scanf("%d",&n);
116         for(int i=1;i<=n;i++)
117             scanf("%s",edge[i].str);
118         sort(edge+1,edge+1+n,cmp);
119         for(int i=1;i<=26;i++)
120             fa[i]=i;
121         for(int i=1;i<=n;i++)
122         {
123             int s=edge[i].str[0]-‘a‘+1,t=edge[i].str[strlen(edge[i].str)-1]-‘a‘+1;
124             add(s,t,i);
125             fa[find(t)]=find(s);
126             degree[s]--;
127             degree[t]++;
128             used[s]=true;
129             used[t]=true;
130         }
131         if(!oula())
132         {
133             printf("***\n");
134         }
135         else
136         {
137             top=0;
138             dfs(start);
139             /*for(int i=1;i<=top-1;i++)
140                 printf("%s.",edge[stack[i]].str);
141             printf("%s\n",edge[stack[top]].str);*/
142             for(int i=top;i>=2;i--)
143                 printf("%s.",edge[stack[i]].str);
144             printf("%s\n",edge[stack[1]].str);
145         }
146     }
147     return 0;
148 }

时间: 2024-10-12 16:19:15

poj 2337 有向图输出欧拉路径的相关文章

poj 2337 Catenyms 【欧拉路径】

题目链接:http://poj.org/problem?id=2337 题意:给定一些单词,假设一个单词的尾字母与还有一个的首字母同样则能够连接.问能否够每一个单词用一次,将全部单词连接,能够则输出字典序最小的序列. 代码: (bin 神的板子) #include <stdio.h> #include <ctime> #include <math.h> #include <limits.h> #include <complex> #include

poj 2337 之 有向图 欧拉路径输出

/* poj 2337 之 有向图 欧拉路径输出  每个单词看作一条有向边,顶点即为单词首尾字母,然后求欧拉路径即可. 1)为保证字典序,先对单词按字典序排序 2)深搜,输出单词序列 */ 1 #include <iostream> 2 #include <fstream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cstddef>

poj 2337 欧拉回路按照最小字典序输出+注意为了按最小字典序怎么处理邻接表

http://poj.org/problem?id=2337 WA了好久,昨晚1点多睡不着写的,狂WA,当时是因为用邻接矩阵存储,比如aba,aa只能存下一个,这个之前还没遇到过,今天才注意到--邻接矩阵无法存储平行边, 关于欧拉回路判断看我另几篇日志或者看我的欧拉总结 再贴个输出欧拉回路的模板 其中,参数u是起点,注意如果是输出欧拉路径的话,u必须是出度比入度大一的那个点,如果输出欧拉回路,随便按要求找个就行 void euler(int u) { for(int i=head[u];i!=-

POJ 2337 Catenyms (欧拉回路+并查集)

题目地址:POJ 2337 这题跟POJ 1386差不多,只不过这题多一个输出路径而已. 按字母来建边,每个单词的首字母和尾字母加边.先判断是否连通,然后判断每个字母的入度和出度不能出现差的绝对值大于2,然后入度和出度差的绝对值为1的不能超过两个.就可以形成欧拉路径 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <alg

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 (有向图欧拉通路)

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 e

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

poj 2337 Catenyms(欧拉路径)

Catenyms 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 ara

POJ 2337 Catenyms

http://poj.org/problem?id=2337 题意: 判断给出的单词能否首尾相连,输出字典序最小的欧拉路径. 思路: 因为要按字典序大小输出路径,所以先将字符串排序,这样加边的时候就会优先加字典序小的边,dfs的时候也就会先走字典序小的边. 判断一下图的连通性以及是否存在欧拉道路. 然后进行深搜寻找欧拉路径,因为欧拉路径时要逆序输出的,所以这里需要先保存起来,最后再次逆序输出即可得到正确的路径. 1 #include<iostream> 2 #include<algori