首页 > 代码库 > poj 1386 欧拉路径

poj 1386 欧拉路径

 1 /*
 2 题意:给出N个单词,一个单词的头字母和另一个单词的尾字母相同则可以相连,问这N个单词是否能完全相连成一行
 3 
 4 题解:求欧拉路径
 5 首先以每个单词的首字母和尾字母为点并且连边,然后用DFS求该图是否连通,然后根据点的入度和出度判断是否存在
 6 欧拉路径或者欧拉回路(存在回路也是符合要求的)
 7 */
 8 #include <cstdio>
 9 #include <cstring>
10 
11 int map[30][30];
12 int in[30],out[30];
13 
14 bool exist[30],vis[30];
15 
16 void dfs(int u)
17 {
18     vis[u] = true;
19     for(int i=0; i<26; i++)
20         if (map[u][i] && exist[i] && !vis[i])
21             dfs(i);
22 }
23 
24 int main(void)
25 {
26     int t;
27     scanf("%d",&t);
28     char str[1005];
29     while (t--)
30     {
31         int n;
32         scanf("%d",&n);
33         memset(map,0,sizeof(map));
34         memset(in,0,sizeof(in));
35         memset(out,0,sizeof(out));
36         memset(exist,false,sizeof(exist));
37 
38         for(int i=0; i<n; i++)
39         {
40             scanf("%s",str);
41             int len = strlen(str);
42             int u = str[0]-a, v = str[len-1]-a;
43             map[u][v]++;
44             in[v] ++;
45             out[u] ++;
46             exist[u] = exist[v] = true;
47         }
48 
49 
50         // 找出合适的起点进行DFS,入度小于出度的肯定是起点,要么就任意起点
51         memset(vis,false,sizeof(vis));
52         int i;
53         for(i=0; i<26; i++)
54             if (exist[i])
55                 break;
56         for(int j=i+1; j<26; j++)
57             if (exist[j] && in[j] < out[j])
58             {
59                 i = j;
60                 break;
61             }
62         dfs(i);
63         for(i=0; i<26; i++) // 连通则所有点都遍历了
64             if (exist[i] && !vis[i])
65                 break;
66 
67         bool flag = false;
68         if (i >= 26)
69         {
70             int head = 0,tail = 0,mid = 0, sum = 0;
71             for(int i=0; i<26; i++)
72             {
73                 if (exist[i])
74                 {
75                     sum++;
76                     if (in[i] == out[i])
77                         mid++;
78                     if (in[i] - out[i] == -1)
79                         head++;
80                     if (in[i] - out[i] == 1)
81                         tail++;
82                 }
83             }
84             if (sum == mid || (head == 1 && tail == 1 && mid == sum-2)) // 判断欧拉路径或回路
85                 flag = true;
86         }
87 
88         if (flag)
89             printf("Ordering is possible.\n");
90         else
91             printf("The door cannot be opened.\n");
92     }
93     return 0;
94 }