首页 > 代码库 > POJ 2337 Catenyms

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 }

 

POJ 2337 Catenyms