POJ 1386 Play on Words(欧拉路)
Posted 谦谦君子,陌上其华
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 1386 Play on Words(欧拉路)相关的知识,希望对你有一定的参考价值。
http://poj.org/problem?id=1386
题意:
给出多个单词,只有单词首字母与上一个单子的末尾字母相同时可以连接,判断所有字母是否可以全部连接在一起。
思路:
判断是否存在欧拉道路,每个单词只需要处理首字母和尾字母就可以了。
还有需要注意的就是需要判断图是否连通,我在这里用了并查集来判断。
有向图D存在欧拉道路的充要条件是:D为有向图,D的基图连通,并且所有顶点的出度与入度都相等;或者除两个顶点外,其余顶点的出度与入度都相等,而这两个顶点中一个顶点的出度与入度之差为1,另一个顶点的出度与入度之差为-1。
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 pair<int,int> pll; 15 const int INF = 0x3f3f3f3f; 16 const int maxn = 1000 + 5; 17 18 int n; 19 int in[30],out[30]; 20 int g[30][30]; 21 int p[30]; 22 char str[maxn]; 23 24 int Find(int x) 25 { 26 return x==p[x]?x:p[x]=Find(p[x]); 27 } 28 29 int main() 30 { 31 //freopen("in.txt","r",stdin); 32 int T; 33 scanf("%d",&T); 34 while(T--) 35 { 36 memset(g,0,sizeof(g)); 37 memset(in,0,sizeof(in)); 38 memset(out,0,sizeof(out)); 39 40 for(int i=0;i<26;i++) p[i]=i; 41 scanf("%d",&n); 42 getchar(); 43 for(int i=0;i<n;i++) 44 { 45 scanf("%s",str); 46 int len=strlen(str); 47 int u=str[0]-‘a‘; 48 int v=str[len-1]-‘a‘; 49 g[u][v]=1; 50 out[u]++; 51 in[v]++; 52 53 int x=Find(u); 54 int y=Find(v); 55 if(x!=y) p[x]=y; 56 } 57 58 int cnt=0; 59 for(int i=0;i<26;i++) 60 { 61 if((in[i]||out[i]) && p[i]==i) 62 cnt++; 63 } 64 if(cnt>1) 65 { 66 puts("The door cannot be opened."); 67 } 68 else 69 { 70 int num1=0,num2=0, num3=0; 71 for(int i=0;i<26;i++) 72 { 73 if(in[i]!=out[i]) 74 { 75 if(in[i]-out[i]==1) num1++; 76 else if(in[i]-out[i]==-1) num2++; 77 else num3++; 78 } 79 } 80 if(num3==0 && ((num1==0 && num2==0)||(num1==1 && num2==1))) 81 puts("Ordering is possible."); 82 else puts("The door cannot be opened."); 83 } 84 } 85 return 0; 86 }
以上是关于POJ 1386 Play on Words(欧拉路)的主要内容,如果未能解决你的问题,请参考以下文章