题目链接:http://poj.org/problem?id=1386

思路分析:该问题要求判断单词是否能连接成一条直线,转换为图论问题:将单词的首字母和尾字母看做一个点,每个单词描述了一条从首字母指向尾字母的有向边,

则则所有的单词构成了一个有向图,问题变为判断该有向图中是否存在一条欧拉路;有向图中存在欧拉路的两个充分必要条件为:该图是联通的并且所有的点的入度等于出度或者只存在两个点的入度与出度不等,一个点的入度=出度+1,另一个点的入度=出度-1;

代码如下:

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. using namespace std;
  5.  
  6. const int MAX_N = ;
  7. const int MAX_M = + ;
  8. int fa[MAX_N], show[MAX_N];
  9. int in[MAX_N], out[MAX_N];
  10. int set_visited[MAX_N];
  11. char str[MAX_M];
  12.  
  13. void Init()
  14. {
  15. for (int i = ; i < MAX_N; ++i)
  16. fa[i] = i;
  17. memset(in, , sizeof(in));
  18. memset(out, , sizeof(out));
  19. memset(show, , sizeof(show));
  20. memset(set_visited, , sizeof(set_visited));
  21. }
  22.  
  23. int Find(int a)
  24. {
  25. if (fa[a] == a)
  26. return a;
  27. else
  28. return fa[a] = Find(fa[a]);
  29. }
  30.  
  31. int Union(int a, int b)
  32. {
  33. int fa_a = Find(a);
  34. int fa_b = Find(b);
  35.  
  36. if (fa_a == fa_b)
  37. return -;
  38. if (fa_a > fa_b)
  39. fa[fa_b] = fa_a;
  40. else
  41. fa[fa_a] = fa_b;
  42. return ;
  43. }
  44.  
  45. int main()
  46. {
  47. int case_times, n, len;
  48.  
  49. scanf("%d", &case_times);
  50. while (case_times--)
  51. {
  52. scanf("%d", &n);
  53. Init();
  54. for (int i = ; i < n; ++i)
  55. {
  56. int l, r;
  57.  
  58. scanf("%s", str);
  59. len = strlen(str);
  60. l = str[] - 'a';
  61. r = str[len - ] - 'a';
  62. in[l]++;
  63. out[r]++;
  64. show[l] = show[r] = ;
  65. Union(l, r);
  66. }
  67. int set_count = ;
  68. int not_equal = ;
  69. int in_big_out = , out_big_in = ;
  70. bool ok = true;
  71. for (int i = ; i < MAX_N; ++i)
  72. {
  73. if (show[i])
  74. {
  75. int fa_i = Find(i);
  76. if (set_visited[fa_i] == )
  77. {
  78. set_count++;
  79. set_visited[fa_i] = ;
  80. }
  81. if (set_count > )
  82. {
  83. ok = false;
  84. break;
  85. }
  86. if (in[i] != out[i])
  87. not_equal++;
  88. if (in[i] == out[i] + )
  89. in_big_out++;
  90. if (in[i] + == out[i])
  91. out_big_in++;
  92. }
  93. }
  94.  
  95. if (!((not_equal == ) || (out_big_in == && in_big_out ==
  96. && in_big_out + out_big_in == not_equal)))
  97. ok = false;
  98.  
  99. if (ok)
  100. printf("Ordering is possible.\n");
  101. else
  102. printf("The door cannot be opened.\n");
  103. }
  104. return ;
  105. }

poj 1386 Play on Words(有向图欧拉路+并查集)的更多相关文章

  1. POJ 1386 Play on Words(欧拉路)

    http://poj.org/problem?id=1386 题意: 给出多个单词,只有单词首字母与上一个单子的末尾字母相同时可以连接,判断所有字母是否可以全部连接在一起. 思路: 判断是否存在欧拉道 ...

  2. poj 1386 Play on Words(有向图欧拉回路)

    /* 题意:单词拼接,前一个单词的末尾字母和后一个单词的开头字母相同 思路:将一个单词的开头和末尾单词分别做两个点并建一条有向边!然后判断是否存在欧拉回路或者欧拉路 再次强调有向图欧拉路或欧拉回路的判 ...

  3. Play on Words(有向图欧拉路)

    Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 8571   Accepted: 2997 Description Some ...

  4. POJ1386Play on Words[有向图欧拉路]

    Play on Words Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11846   Accepted: 4050 De ...

  5. 【POJ 1988】 Cube Stacking (带权并查集)

    Cube Stacking Description Farmer John and Betsy are playing a game with N (1 <= N <= 30,000)id ...

  6. 【POJ 1984】Navigation Nightmare(带权并查集)

    Navigation Nightmare Description Farmer John's pastoral neighborhood has N farms (2 <= N <= 40 ...

  7. POJ 1703 Find them, Catch them (数据结构-并查集)

    Find them, Catch them Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 31102   Accepted: ...

  8. POJ 1984 Navigation Nightmare 【经典带权并查集】

    任意门:http://poj.org/problem?id=1984 Navigation Nightmare Time Limit: 2000MS   Memory Limit: 30000K To ...

  9. [poj 2912] Rochambeau 解题报告 (带权并查集)

    题目链接:http://poj.org/problem?id=2912 题目: 题目大意: n个人进行m轮剪刀石头布游戏(0<n<=500,0<=m<=2000) 接下来m行形 ...

随机推荐

  1. Oracle中的日期和字符串互相转换

    转载出处:http://blog.sina.com.cn/s/blog_44a005380100k6rv.html TO_DATE格式(以时间:2007-11-02   13:45:25为例)    ...

  2. Struts2相关注意点

    今天开始学习Struts2,有一个小栗子用到了DMI动态方法调用,使用DMI可以减少action的数量简化程序,不用在struts.xml的action中定义method属性.刚开始怎么也不能使用DM ...

  3. Django Web开发【7】 投票与评论

    为了让用户更好的发现和共享bookmark,可以提供投票与评论功能.现在我们的主页还是一个很简单的欢迎页面,我们可以让用户在主页共享自己的bookmark,此外,用户还可以对主页的bookmark进行 ...

  4. PHP查询MYSQL表的主键

    $sql = "SELECT * from Person"; $result = mysql_query($sql,$con); while ($property = mysql_ ...

  5. C iOcp

    #include <winsock2.h> //#include <windows.h> #include <stdio.h> #define PORT 5150 ...

  6. codeforces 292E. Copying Data 线段树

    题目链接 给两个长度为n的数组, 两种操作. 第一种, 给出x, y, k, 将a[x, x+k-1]这一段复制到b[y, y+k-1]. 第二种, 给出x, 输出b[x]的值. 线段树区间更新单点查 ...

  7. Linux 关机

    1. shutdown shutdown -h now 立刻关机 shutdown -h 22:50 22:50 分的时候关机 shutdown -h +10 10分钟后关机 shutdwon -r ...

  8. RTTI-CLASS

    package com.xt.test; interface Test1Interface { } interface Test2Interface { } class Test1 implement ...

  9. [问题解决] File "/struts-tags" not found

    错误:org.apache.jasper.JasperException: File "/struts-tags" not found 发生场景:tomcat服务器 解决方案:将t ...

  10. 组合框里添加复选框的方法(使用勾选的假象,用图片代替而已,并非QT原生支持)

    组合框可以看作是列表框和文本框的组合,因其占据的空间少,使用操作方便,常被界面设计人员用于界面开发设计中,在有限个输入的条件下,组合框常用来代替文本框,这样从用户使用角度来看,更趋人性化,所见即所得. ...