POJ 1386(欧拉路)

因为要求每个单词只是用一次,还要构成串,很容易想到欧拉路。

把单词抽象成一条边,首字母和末字母为边的两个端点,判断有向图欧拉路就行了

PS:注意判断连通性,判断连通性构图需要是双向的

 

View Code
 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cstring>
 4 using namespace std;
 5 int in[30],out[30],sum,num,n,tt,st,len;
 6 bool map[30][30],vis[30];
 7 char ls[10000];
 8 void dfs(int u)
 9 {
10     vis[u]=true;
11     num++;
12     for(int i=1;i<=26;i++)
13         if(map[u][i]&&!vis[i]) dfs(i);
14 }
15 bool read()
16 {
17     memset(in,0,sizeof in);
18     memset(out,0,sizeof out);
19     memset(map,0,sizeof map);
20     memset(vis,0,sizeof vis);
21     sum=0;num=0;
22     scanf("%d\n",&n);
23     for(int i=1;i<=n;i++)
24     {
25         scanf("%s",ls+1);
26         len=strlen(ls+1);
27         out[ls[1]-'a'+1]++;
28         in[ls[len]-'a'+1]++;
29         map[ls[1]-'a'+1][ls[len]-'a'+1]=map[ls[len]-'a'+1][ls[1]-'a'+1]=1;
30     }
31 
32     for(int i=1;i<=26;i++) 
33     {
34         if(in[i]||out[i]) sum++;
35         if(out[i]) st=i;
36     }
37     memset(vis,0,sizeof vis);
38     dfs(st);//printf("st:%d\n",st);    //system("pause");
39     if(num==sum) {return true;}
40     else return false;
41 }
42 void go()
43 {
44     int a=0,b=0;
45     for(int i=1;i<=26;i++)
46     {
47         if(in[i]==out[i]+1) b++;
48         else if(out[i]==in[i]+1) a++;
49         else if(in[i]==out[i]) continue;
50         else 
51         {
52             printf("The door cannot be opened.\n");
53             return;
54         }
55     }
56     if(a<=1&&b<=1) printf("Ordering is possible.\n");
57     else printf("The door cannot be opened.\n");
58 }
59 int main()
60 {
61     scanf("%d",&tt);
62     while(tt--)
63     {
64         if(!read()) printf("The door cannot be opened.\n");
65         else go();
66     }
67     system("pause");
68     return 0;
69 }

 

 

posted @ 2012-08-29 13:06  proverbs  阅读(200)  评论(0编辑  收藏  举报