Play on Words

poj1386:http://poj.org/problem?id=1386

题意:给你n个单词,问你是否能够通过调整单词的顺序存在这样的一个序列,使得 每个单词的首字母是前一个单词的尾字母。
 题解:每个单词可以看做从首字母连向尾字母的一条边,然后就是整个图的欧拉路径。统计每个点的入度和初度,如果基图连通,并且只有两个点入度和初度不等,并且相差分别为1,-1,就存在这样的路径,否则则没。 连通性,可以用并查集. 处理完之后,看每个点的父亲是否相等来判断是否连通。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cstdio>
 5 using namespace  std;
 6 int in[27], pa[27], out[27];// 统计入度,初读 
 7 bool used[27];//记录出现过的字母 
 8 int n;//单词的个数 
 9 char str[1000];//读取单词 
10 void UFset(){//初始化 
11     for(int i=1;i<=26;i++){
12         used[i]=0;
13          pa[i]=-1;
14          out[i]=0;
15          in[i]=0;
16     }
17 }
18 int Find(int x){//查找 
19     int s;
20     for(s=x;pa[s]>=0;s=pa[s]);
21     while(s!=x){
22         int temp=pa[x];
23         pa[x]=s;
24         x=temp;
25     }
26     return s;
27 }
28 void Union(int R1,int R2){//合并 
29     int r1=Find(R1);
30     int r2=Find(R2);
31     int temp=pa[r1]+pa[r2];
32     if(pa[r1]>pa[r2]){
33         pa[r1]=r2;
34         pa[r2]=temp;
35     }
36     else{
37         pa[r2]=r1;
38         pa[r1]=temp;
39     }
40 }
41 bool solve(){//判断连通性 
42     int first=-1;
43     for(int i=1;i<=26;i++){
44         if(!used[i])continue;
45         if(first==-1)first=Find(i);
46         else if(first!=Find(i))return false;
47     }
48     return true;
49 }
50 int main(){
51   int cas;
52    scanf("%d",&cas);
53    while(cas--){
54        scanf("%d",&n);
55        UFset();
56        for(int i=1;i<=n;i++){//建图 
57            scanf("%s",str);
58            int len=strlen(str);
59            int u=str[0]-'a'+1;
60            int v=str[len-1]-'a'+1;
61              in[v]++;
62              used[v]=true;
63              out[u]++;used[u]=true;
64              if(Find(u)!=Find(v))
65                Union(u,v);
66         }
67         int one=0,one1=0;bool flag=true;
68     for(int j=1;j<=26;j++){
69       if(!used[j])continue;
70            if(out[j]-in[j]>=2||in[j]-out[j]>=2){
71                flag=false;
72                break;
73            }
74            if(out[j]-in[j]==1){
75                one++;
76                if(one>1)
77                    {flag=false;break;}
78            }
79                if(out[j]-in[j]==-1){
80                one1++;
81                if(one1>1){
82                    flag=false;break;
83                }
84               }
85        }       
86        if(one!=one1)flag=false;
87        if(!solve())flag=false;
88        if(flag)printf("Ordering is possible.\n");
89        else
90        printf("The door cannot be opened.\n");
91        }
92 }
View Code

 

posted on 2013-10-23 08:49  天依蓝  阅读(306)  评论(0编辑  收藏  举报

导航