码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 1116 || POJ 1386 || ZOJ 2016 Play on Words (欧拉回路+并查集)

时间:2014-07-30 11:54:33      阅读:229      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   io   for   art   

题目链接

题意 : 有很多门,每个门上有很多磁盘,每个盘上一个单词,必须重新排列磁盘使得每个单词的第一个字母与前一个单词的最后一个字母相同。给你一组单词问能不能排成上述形式。

思路 :把每个单词看成有首字母指向尾字母的有向边,每个字母看成一个点,题中要求等效于判断图中是否存在一条路径经过每一条一次且仅一次,就是有向欧拉通路。统计个顶点的出入度,如果每个点的出入度都相同,那就是欧拉回路,如果有两个奇数度,那就是欧拉通路,除此之外,都不能满足要求。还有别忘了判断是否连通,此时用到并查集,图中所有的边(u,v),如果u!=v且属于不同的连通分量,就合并。欧拉回路的基本定理及概念。

bubuko.com,布布扣
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 
 5 using namespace std ;
 6 
 7 char word[1001] ;
 8 int father[27],out[27],in[27] ,vis[30];
 9 
10 int find_(int x)
11 {
12     if(father[x] != x)
13         father[x] = find_(father[x]) ;
14     return father[x] ;
15 }
16 
17 void mergee(int a,int b)
18 {
19     if(find_(a) != find_(b))
20         father[find_(a)] = find_(b) ;
21 }
22 
23 void Init()
24 {
25     memset(out,0,sizeof(out)) ;
26     memset(in,0,sizeof(in)) ;
27     for(int i = 0 ; i < 26 ; i++)
28         father[i] = i ;
29     memset(vis,0,sizeof(vis)) ;
30 }
31 
32 int main()
33 {
34     int T ;
35     cin >> T ;
36     int n ;
37     while(T--)
38     {
39         cin >> n ;
40         Init() ;
41         while(n -- )
42         {
43             scanf("%s",word) ;
44             int u = word[0]-a ;
45             int v = word[strlen(word)-1]-a ;
46             mergee(u,v) ;
47             out[u] ++ ;
48             in[v] ++ ;
49             vis[u] = vis[v] = 1 ;
50         }
51         int cnt = 0,cnt1 = 0 ,cnt2 = 0 ;
52         for(int i = 0 ; i < 26 ; i++)
53         {
54             if(vis[i] && father[i] == i)
55             {
56                 cnt ++ ;
57             }
58         }
59         if(cnt > 1)
60         {
61             puts("The door cannot be opened.") ;
62             continue ;
63         }
64         bool flag = true ;
65         for(int i = 0 ; i < 26 ; i++)
66         {
67             if(vis[i] && out[i] != in[i])
68             {
69                 if(out[i]-in[i] == 1)
70                 {
71                     cnt1 ++ ;
72                     if(cnt1 > 1)
73                     {
74                         flag = false ;
75                         break ;
76                     }
77                 }
78                 else if(in[i]-out[i] == 1)
79                 {
80                     cnt2 ++ ;
81                     if(cnt2 > 1)
82                     {
83                         flag = false ;
84                         break ;
85                     }
86                 }
87                 else
88                 {
89                     flag = false ;
90                     break ;
91                 }
92             }
93         }
94         if(!flag) puts("The door cannot be opened.") ;
95         else puts("Ordering is possible.") ;
96     }
97     return 0 ;
98 }
View Code

 

HDU 1116 || POJ 1386 || ZOJ 2016 Play on Words (欧拉回路+并查集),布布扣,bubuko.com

HDU 1116 || POJ 1386 || ZOJ 2016 Play on Words (欧拉回路+并查集)

标签:style   blog   http   color   os   io   for   art   

原文地址:http://www.cnblogs.com/luyingfeng/p/3877361.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!