hdu 1116(併査集+オーラル判断)
12814 ワード
タイトルリンク:http://acm.hdu.edu.cn/showproblem.php?pid=1116
考え方:まず合併して、それから根の結点が唯一かどうかを判断して、もしそうならば、オラ路かどうかを判断します;そうでなければ、直接終わります.
View Code
考え方:まず合併して、それから根の結点が唯一かどうかを判断して、もしそうならば、オラ路かどうかを判断します;そうでなければ、直接終わります.
View Code
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 using namespace std;
5 const int MAXN=100000+10;
6 int In[MAXN],Out[MAXN];
7 int parent[MAXN];
8 bool mark[MAXN];
9 int n;
10
11
12 void Initiate(){
13 for(int i=0;i<n;i++){
14 parent[i]=-1;
15 }
16 }
17
18 int Find(int x){
19 int s;
20 for(s=x;parent[s]>=0;s=parent[s]);
21 while(s!=x){
22 int tmp=parent[x];
23 parent[x]=s;
24 x=tmp;
25 }
26 return s;
27 }
28
29 void Union(int R1,int R2){
30 int r1=Find(R1);
31 int r2=Find(R2);
32 if(r1!=r2){
33 parent[r1]=r2;
34 }
35 }
36
37 int main(){
38 int _case;
39 scanf("%d",&_case);
40 while(_case--){
41 scanf("%d",&n);
42 Initiate();
43 memset(mark,false,sizeof(mark));
44 memset(In,0,sizeof(In));
45 memset(Out,0,sizeof(Out));
46 for(int i=0;i<n;i++){
47 char str[1010];
48 scanf("%s",str);
49 int x=str[0]-'a';
50 int y=str[strlen(str)-1]-'a';
51 Union(x,y);
52 mark[x]=mark[y]=true;
53 Out[x]++;
54 In[y]++;
55 }
56 int count=0;
57 for(int i=0;i<26;i++){
58 if(mark[i]&&parent[i]==-1){
59 count++;
60 }
61 }
62 if(count>1){
63 printf("The door cannot be opened.
");
64 }else {
65 int p[27];
66 int k=0;
67 for(int i=0;i<26;i++){
68 if(mark[i]&&In[i]!=Out[i]){
69 p[k++]=i;
70 }
71 }
72 if(k==0){
73 printf("Ordering is possible.
");
74 }else {
75 if(k==2&&abs(In[p[0]]-Out[p[0]])==1&&abs(In[p[1]]-Out[p[1]])==1){
76 printf("Ordering is possible.
");
77 }else
78 printf("The door cannot be opened.
");
79 }
80 }
81 }
82 return 0;
83 }