POJ 2337 Catenyms

http://poj.org/problem?id=2337

题意:

判断给出的单词能否首尾相连,输出字典序最小的欧拉路径。

思路:

因为要按字典序大小输出路径,所以先将字符串排序,这样加边的时候就会优先加字典序小的边,dfs的时候也就会先走字典序小的边。

判断一下图的连通性以及是否存在欧拉道路。

然后进行深搜寻找欧拉路径,因为欧拉路径时要逆序输出的,所以这里需要先保存起来,最后再次逆序输出即可得到正确的路径。

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<sstream>
  6 #include<vector>
  7 #include<stack>
  8 #include<queue>
  9 #include<cmath>
 10 #include<map>
 11 #include<set>
 12 using namespace std;
 13 typedef long long ll;
 14 typedef long long ull;
 15 typedef pair<int,int> pll;
 16 const int INF = 0x3f3f3f3f;
 17 const int maxn = 1000 + 5;
 18
 19 struct Edge
 20 {
 21     int ID;
 22     int v;
 23     int vis;
 24     Edge(){}
 25     Edge(int id,int x,int y):ID(id),v(x),vis(y){}
 26 };
 27
 28 int n;
 29 int p[30];
 30 int in[30], out[30];
 31 string str[maxn];
 32
 33 vector<Edge> G[maxn];
 34
 35 stack<int> sta;
 36
 37 int Find(int x)
 38 {
 39     return p[x]==x?x:p[x]=Find(p[x]);
 40 }
 41
 42 void Fleury(int u)
 43 {
 44     for(int i=0;i<G[u].size();i++)
 45     {
 46         if(!G[u][i].vis)
 47         {
 48             G[u][i].vis=1;
 49             Fleury(G[u][i].v);
 50             sta.push(G[u][i].ID);   //这儿是逆序存储
 51         }
 52     }
 53 }
 54
 55 int main()
 56 {
 57     //freopen("in.txt","r",stdin);
 58     int T;
 59     scanf("%d",&T);
 60     while(T--)
 61     {
 62         memset(in,0,sizeof(in));
 63         memset(out,0,sizeof(out));
 64
 65         scanf("%d",&n);
 66         for(int i=0;i<26;i++)  {G[i].clear();p[i]=i;}
 67
 68         for(int i=0;i<n;i++)   cin>>str[i];
 69         sort(str,str+n);  //排序,按照字典序顺序加边,这样等下dfs的时候就会先选择字典序小的边
 70
 71         int start;
 72         for(int i=0;i<n;i++)
 73         {
 74             int a=str[i][0]-‘a‘;
 75             int b=str[i][str[i].size()-1]-‘a‘;
 76             out[a]++;
 77             in[b]++;
 78             int x=Find(a);
 79             int y=Find(b);
 80             if(x!=y)  p[x]=y;
 81             G[a].push_back(Edge(i,b,0));
 82             if(i==0)  start=a;
 83         }
 84
 85         int cnt=0;
 86         int num1=0,num2=0,num3=0;
 87         for(int i=0;i<26;i++)
 88         {
 89             if((in[i]||out[i]) && p[i]==i)  cnt++;
 90             if(in[i]!=out[i])
 91             {
 92                 if(out[i]-in[i]==1)   {start=i;num1++;}
 93                 else if(out[i]-in[i]==-1)   num2++;
 94                 else num3++;
 95             }
 96         }
 97
 98         if(!num3 && ((num1==0 && num2==0) || (num1==1 && num2==1)) && cnt==1)
 99         {
100             Fleury(start);
101             cout<<str[sta.top()]; sta.pop();
102             while(!sta.empty())
103             {
104                 cout<<"."<<str[sta.top()];
105                 sta.pop();
106             }
107             cout<<endl;
108         }
109         else {puts("***");continue;}
110     }
111 }
时间: 2024-10-12 03:52:21

POJ 2337 Catenyms的相关文章

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

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

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 【欧拉路径】

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

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 欧拉通路

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

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