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