2.解题思路:本题利用欧拉回路存在条件解决。可以将所有的单词看做边,26个字母看做端点,那么本题其实就是问是否存在一条路径,可以到达所有出现过的字符端点。由于本题还要求了两个单词拼在一起的条件是前一个单词的右端点和本单词的左端点一样。所以这是一个有向图。根据结论:有向图的底图(忽略边的方向后的图)必须连通;有向图中最多只能有两个端点的入度不等于出度,且必须是其中一点的入度比出度小1,另一点的入度比出度大1。因此先判断端点是否都连通,再判断每个端点的度数是否满足结论即可。

那么,如何判断连通性呢?第一种方法是利用DFS,第二种方法可以利用并查集。本题利用并查集来判断是否连通。

  1. #pragma comment(linker, "/STACK:1024000000,1024000000")
  2. #include<iostream>
  3. #include<cstdio>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<math.h>
  7. #include<algorithm>
  8. #include<queue>
  9. #include<set>
  10. #include<bitset>
  11. #include<map>
  12. #include<vector>
  13. #include<stdlib.h>
  14. #include <stack>
  15. using namespace std;
  16. int dirx[]={,,-,};
  17. int diry[]={-,,,};
  18. #define PI acos(-1.0)
  19. #define max(a,b) (a) > (b) ? (a) : (b)
  20. #define min(a,b) (a) < (b) ? (a) : (b)
  21. #define ll long long
  22. #define eps 1e-10
  23. #define MOD 1000000007
  24. #define N 100006
  25. #define inf 1e12
  26. int n;
  27. int u[N],v[N];
  28. int in[N],out[N];
  29. int vis[N];
  30. int fa[N];
  31. int num;
  32. void init(){
  33. memset(in,,sizeof(in));
  34. memset(out,,sizeof(out));
  35. memset(vis,,sizeof(vis));
  36. for(int i=;i<N;i++){
  37. fa[i]=i;
  38. }
  39. num=;
  40. }
  41. /////////////////////////////////////////////////////////////////////
  42. int find(int x){
  43. return fa[x]==x?x:fa[x]=find(fa[x]);
  44. }
  45. void merge(int x,int y){
  46. int root1=find(x);
  47. int root2=find(y);
  48. if(root1==root2) return;
  49. fa[root1]=root2;
  50. }
  51. //////////////////////////////////////////////////////////////////////
  52. void solve(){
  53.  
  54. for(int i=;i<n;i++){
  55. merge(u[i],v[i]);
  56. }
  57. int i=;
  58. for(i;!vis[i];i++);
  59.  
  60. int x=find(i);//判断能否连通
  61. for(int j=i+;j<;j++){
  62. if(vis[j]){
  63. int y=find(j);
  64. if(x!=y){
  65. printf("The door cannot be opened.\n");
  66. return;
  67. }
  68. }
  69. }
  70.  
  71. int flag=;
  72. int cnt=;
  73. for(int i=;i<;i++){
  74. if(vis[i]){
  75. if(in[i]!=out[i]){
  76. if(in[i]==out[i]-) cnt++;
  77. else if(in[i]==out[i]+) cnt++;
  78. else{
  79. flag=;
  80. break;
  81. }
  82. }
  83. if(cnt>){
  84. flag=;
  85. break;
  86. }
  87. }
  88. }
  89. if(flag){
  90. printf("Ordering is possible.\n");
  91. }
  92. else{
  93. printf("The door cannot be opened.\n");
  94. }
  95.  
  96. }
  97. int main()
  98. {
  99. int t;
  100. scanf("%d",&t);
  101. while(t--){
  102.  
  103. init();
  104.  
  105. char s[];
  106. scanf("%d",&n);
  107. for(int i=;i<n;i++){
  108. scanf("%s",s);
  109. int len=strlen(s);
  110. int a=s[]-'a';
  111. int b=s[len-]-'a';
  112. u[i]=a,v[i]=b;
  113. in[a]++,out[b]++;
  114. vis[a]=;
  115. vis[b]=;
  116. }
  117. solve();
  118. }
  119. return ;
  120. }

UVA - 10129 Play on Words(欧拉回路+并查集)的更多相关文章

  1. UVa 10129 Play on Words(并查集+欧拉路径)

    题目链接: https://cn.vjudge.net/problem/UVA-10129 Some of the secret doors contain a very interesting wo ...

  2. ACM: FZU 2112 Tickets - 欧拉回路 - 并查集

     FZU 2112 Tickets Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u P ...

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

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

  4. POJ2513——Colored Sticks(Trie树+欧拉回路+并查集)

    Colored Sticks DescriptionYou are given a bunch of wooden sticks. Each endpoint of each stick is col ...

  5. nyist 42 一笔画 (欧拉回路 + 并查集)

    nyoj42 分析: 若图G中存在这样一条路径,使得它恰通过G中每条边一次,则称该路径为欧拉路径. 若该路径是一个圈,则称为欧拉(Euler)回路. 具有欧拉回路的图称为欧拉图(简称E图).具有欧拉路 ...

  6. poj 1386 Play on Words门上的单词【欧拉回路&&并查集】

    题目链接:http://poj.org/problem?id=1386 题目大意:给你若干个字符串,一个单词的尾部和一个单词的头部相同那么这两个单词就可以相连,判断给出的n个单词是否能够一个接着一个全 ...

  7. POJ 2513 Colored Sticks (欧拉回路+并查集+字典树)

    题目链接 Description You are given a bunch of wooden sticks. Each endpoint of each stick is colored with ...

  8. PAT甲题题解-1126. Eulerian Path (25)-欧拉回路+并查集判断图的连通性

    题目已经告诉如何判断欧拉回路了,剩下的有一点要注意,可能图本身并不连通. 所以这里用并查集来判断图的联通性. #include <iostream> #include <cstdio ...

  9. hdu 1116 欧拉回路+并查集

    http://acm.hdu.edu.cn/showproblem.php?pid=1116 给你一些英文单词,判断所有单词能不能连成一串,类似成语接龙的意思.但是如果有多个重复的单词时,也必须满足这 ...

随机推荐

  1. ios 导航栏和旋屏

    1,状态栏(UIStatusBar) http://my.oschina.net/shede333/blog/304560 2,visibleViewController和topViewControl ...

  2. poj 2305(指定进制,大数取模)

    题意:输入一个进制b,在输入两个基于b进制的大整数 x,y ,求x%y的b进制结果. http://162.105.81.212/JudgeOnline/problem?id=2305 函数: Str ...

  3. Linux权限管理(笔记)

    权限管理:r: w:x: 三类用户:u: 属主g: 属组o: 其它用户 chown: 改变文件属主(只有管理员可以使用此命令)# chown USERNAME file,...    -R: 修改目录 ...

  4. shell中eval命令妙用——变量嵌套替换

    eval命令妙用--变量嵌套替换 eval命令在Linux下的应用非常广泛,在写脚本的时候遇到一个变量嵌套的问题,用eval迎刃而解,略试不爽啊. var1="hello" i=1 ...

  5. 用dTree组件生成无限级导航树

     在做管理系统时不可避免要用到导航树,这种东西只要一次做好,就可以随处运行,目前比较好的组件是dTree,原则上可以达到无限级,当然实际运行中4,5级就已经很多了,dTree的速度还是不错的,而且是J ...

  6. LinqToXML~读XML文件续

    上篇文章读了如何通过linq to xml去读取XML文件,而这讲主要通过linq to xml来读取由属性组件的XML文件,例如读取一个web.config的XML格式的配置文件,下面是config ...

  7. Linux shell编程 4 ---- shell中的循环

    1 for循环 1 for语句的结构 for variable in values; do statement done 2 for循环通常是用来处理一组值,这组值可以是任意的字符串的集合 3 for ...

  8. 使用WeCloud消息推送接口发送消息NodeJs版

    WeCloud是一家初创公司的产品,眼下主要在做Android和IOS消息推送这块.他们提供了用于向设备发送消息的协议,详细协议内容见消息推送协议. 这篇文章将使用NodeJs基于这个推送协议完毕向A ...

  9. LabView 下载与安装

    labview2014是目前labview软件的最新版本,新版本增加了多个VI服务器对象,增加了多个vi脚本对象,增加了labview第三方许可和激活工具包,同时针对程序框图.编辑环境.应用程序生成器 ...

  10. js判断是否是数字通用写法

    function isNumber(value){ var isNumber = value.match(/^(-?\d+)(\.\d+)?$/g) !=null; if(value.substrin ...