poj1386--Play on Words--欧拉路
Description
给你若干个单词,一个单词能拼接到前一个单词的标准是:此单词的首字母和前一个单词的尾字母相同。
Sample Input
3 2 acm ibm 3 acm malform mouse 2 ok ok
Sample Output
The door cannot be opened. Ordering is possible. The door cannot be opened.
题解:
构图:每个单词对应一条有向边,从此单词的首字母连向尾字母。如果其中存在欧拉路,说明可以拼接成链(欧拉通路)或环(欧拉回路)。
首先存储字母出现的信息,因为是多组数据,注意每次要初始化记录数组。
同时用used数组标记该字母是否出现在图中,in数组和out数组分别记录入度和出度。
用一个并查集对整个构成的图做合并处理,判断此图是否没有孤立的点,如果有,说明不连通,需要输出“The door cannot be opend."
如果整张图联通,进一步遍历这张图。
接下来判断是否是欧拉路:
1.如果有任何一个点的出入度之差大于1,就不是欧拉路;
2.记录出入度不相等的点,如果入度-出度=1的点超过1个,说明终点超过1个,不是欧拉路;
3.记录出入度不相等的点,如果出度-入度=1的点超过1个,说明起点超过了1个,也不是欧拉路。
1 #include<algorithm> 2 #include<cmath> 3 #include<cstdio> 4 #include<cstring> 5 #include<iostream> 6 using namespace std; 7 const int maxn=100009; 8 9 int n,m,in[maxn],out[maxn],fa[maxn]; 10 bool used[maxn]; 11 12 void init() 13 { 14 memset(used,0,sizeof(used)); 15 memset(in,0,sizeof(in)); 16 memset(out,0,sizeof(out)); 17 for(int i=1;i<=n;i++) 18 fa[i]=i; 19 } 20 21 int find(int x) 22 { 23 if(x!=fa[x]) 24 fa[x]=find(fa[x]); 25 return fa[x]; 26 } 27 28 void uni_set(int x,int y) 29 { 30 int u=find(x),v=find(y); 31 if(u==v) 32 return; 33 fa[u]=v; 34 } 35 36 bool judge_eular() 37 { 38 int sta=0,end=0; 39 for(int i=1;i<=26;i++) 40 { 41 if(used[i]) 42 { 43 if(abs(in[i]-out[i])>1)return 0; 44 if(in[i]-out[i]==1) 45 { 46 end++; 47 if(end>1)return 0; 48 } 49 if(out[i]-in[i]==1) 50 { 51 sta++; 52 if(sta>1)return 0; 53 } 54 } 55 } 56 return 1; 57 } 58 59 int main() 60 { 61 int T; 62 scanf("%d",&T); 63 while(T--) 64 { 65 scanf("%d",&n); 66 init(); 67 int tmp; 68 char a[1009]; 69 for(int i=1;i<=n;i++) 70 { 71 scanf("%s",a); 72 int len=strlen(a); 73 int u=a[0]-'a'+1, v=a[len-1]-'a'+1; 74 in[v]++;out[u]++; 75 used[u]=used[v]=1; 76 tmp=v; 77 uni_set(u,v); 78 } 79 tmp=find(tmp); 80 bool ok=1; 81 for(int i=1;i<=26;i++) 82 { 83 if(used[i]&&tmp!=find(i)) 84 { 85 printf("The door cannot be opened.\n"); 86 ok=0; 87 break; 88 } 89 } 90 if(ok) 91 { 92 if(!judge_eular()) 93 { 94 printf("The door cannot be opened.\n"); 95 ok=0; 96 } 97 else 98 { 99 printf("Ordering is possible.\n"); 100 ok=1; 101 } 102 } 103 } 104 return 0; 105 }