题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1116

离散数学的知识,囧,这一块没怎么学,基础很薄弱啊。

不过对于欧拉回路/通路的结论,倒是不难推出。

欧拉通路:除首尾结点外,其余结点入度等于出度,起点出度减入度等于1,终点入度减出度等于1

欧拉回路:所有结点的入度都等于出度

思路:将每一个单词的首尾字母当做结点,首尾字母间连线,判断最后形成的有向图能否形成欧拉通路/回路,用并查集。

这题直接参考了网上的。

代码:

1 #include<stdio.h>
2 #include<string.h>
3 #define N 27
4 int out[N],in[N],flag[N],p[N],father[N];
5 int find(int x)
6 {
7     int r=x;
8     while(father[r]!=r)
9         r=father[r];
10     return r;
11 }
12 void Union(int a,int b)
13 {
14     int fx,fy;
15     fx=find(a);
16     fy=find(b);
17     if(fx!=fy)
18         father[fx]=fy;
19 }
20 int main()
21 {
22     int i,k,cnt,a,b,ncase,n;
23     char s[1002];
24     scanf("%d",&ncase);
25     while(ncase--)
26     {
27         for(i=0;i<26;i++)
28             father[i]=i;  //初始化
29         memset(in,0,sizeof(in));
30         memset(out,0,sizeof(out));
31         memset(flag,0,sizeof(flag));
32         scanf("%d",&n);
33         for(i=1;i<=n;i++)
34         {
35             scanf("%s",s);
36             a=s[0]-'a';
37             b=s[strlen(s)-1]-'a';
38             Union(a,b);
39             in[b]++;
40             out[a]++;
41             flag[a]=flag[b]=1;
42         }
43         cnt=0;
44         for(i=0;i<26;i++)
45         {
46             father[i]=find(i);
47             if(flag[i] && father[i]==i)
48                 cnt++;  //计算连通分支个数
49         }
50         if(cnt>1)  //不是连通图
51         {
52             printf("The door cannot be opened.\n");
53             continue;
54         }
55         k=0;
56         for(i=0;i<26;i++)
57         {
58             if(flag[i] && in[i]!=out[i])
59                 p[k++]=i;  //计算入度不等于出度的结点数
60         }
61         if(k==0)  //是欧拉回路
62         {
63             printf("Ordering is possible.\n");
64             continue;
65         }
66         if(k==2 && (out[p[0]]-in[p[0]]==1 && in[p[1]]-out[p[1]]==1
67             || out[p[1]]-in[p[1]]==1 && in[p[0]]-out[p[0]]==1) )
68         {   //是欧拉通路
69             printf("Ordering is possible.\n");
70             continue;
71         }
72         printf("The door cannot be opened.\n");
73     }
74     return 0;
75 }