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

题意:给定n个人和m个群,接下来是m行,每行给出该群内的人数以及这些人所对应的编号。需要统计出跟编号0的人有直接或间接关系的人数总共有多少。

这又是一条并查集的应用。难点是如何统计出与0有关系的总人数,即包含0的集合内元素的总个数。我的方法是用了两次merge,第一次merge单纯地将同一群内的元素连边,当然该群内的元素的祖先有可能是别的群内的元素,连边的规则是大的元素指向小的元素;第二次merge则把第一次筛选出来的集合中将元素与它的祖先再合并。目的是为了每一个集合内的元素都指向同一个代表。

以第一个数据测试来说,第二行的 2  1  2,把编号1和2的人连边,此时p[1] = 1, p[2] = 1;

第四行的  2   0   1,把编号0和1的人连边,此时p[0] = 0,p[1]  = 0;第五行的 2  99  2,结果p[99] = 0,p[2] = 1。(p[99] 指向元素2的祖先,而2的祖先1的祖先为0,因此p[99] = 0)。处理完问题出现了,第一次merge并不能使p[2]指向0,它还是保持1,因此第二次merge就有必要设置了。它使得p[2] = 0。由于代表为0的集合上所有的元素都指向0,因此最后统计哪些祖先是0的集合个数就是答案了。

  1. #include <iostream>
  2. using namespace std;
  3.  
  4. const int maxn = + ;
  5. int p[maxn];
  6.  
  7. int find(int x)
  8. {
  9. while (x != p[x])
  10. x = p[x];
  11. return x;
  12. }
  13.  
  14. void merge(int x, int y)
  15. {
  16. int fx = find(x);
  17. int fy = find(y);
  18. if (fx > fy) // 从一开始就保证大的元素指向小的元素,即大的元素的祖先是小的元素
  19. p[fx] = fy;
  20. else
  21. p[fy] = fx;
  22. }
  23.  
  24. void merge1(int x, int y) // 第二次merge很关键
  25. {
  26. int fx = find(x);
  27. int fy = find(y);
  28. if (fx > fy) // 数组下标与第一次merge是不同的!!!
  29. p[x] = fy;
  30. else
  31. p[y] = fx;
  32. }
  33.  
  34. int main()
  35. {
  36. int i, j, n, m, t, x, k;
  37. while (scanf("%d%d", &n, &m) != EOF && (m || n))
  38. {
  39. if (m == ) // 特殊情况没有群,此时只有0这个学生是嫌疑犯
  40. printf("1\n");
  41. else
  42. {
  43. for (i = ; i < n; i++)
  44. {
  45. p[i] = i;
  46. }
  47. for (i = ; i < m; i++)
  48. {
  49. scanf("%d", &k);
  50. scanf("%d", &t); // 每组中第一个人要单独输入,为了下面的merge操作方便
  51. for (j = ; j < k; j++)
  52. {
  53. scanf("%d", &x);
  54. merge(t, x);
  55. // printf("p[%d] = %d, p[%d] = %d\n", t, p[t], x, p[x]);
  56. t = x;
  57. }
  58. }
  59. int cnt = ; // 编号为0这个人
  60. for (i = ; i < n; i++)
  61. {
  62. if (p[i] != i) // 第一轮merge后的再一次处理
  63. {
  64. merge1(p[i], i);
  65. // printf("p[%d] = %d\n", i, p[i]);
  66. if (p[i] == )
  67. cnt++;
  68. }
  69. }
  70. printf("%d\n", cnt);
  71. }
  72. }
  73. return ;
  74. }

poj 1611 The Suspects 解题报告的更多相关文章

  1. 【原创】poj ----- 1611 The Suspects 解题报告

    题目地址: http://poj.org/problem?id=1611 题目内容: The Suspects Time Limit: 1000MS   Memory Limit: 20000K To ...

  2. Tarjan算法求解桥和边双连通分量(附POJ 3352 Road Construction解题报告)

     http://blog.csdn.net/geniusluzh/article/details/6619575 在说Tarjan算法解决桥和边双连通分量问题之前我们先来回顾一下Tarjan算法是如何 ...

  3. POJ 3126 Prime Path 解题报告(BFS & 双向BFS)

    题目大意:给定一个4位素数,一个目标4位素数.每次变换一位,保证变换后依然是素数,求变换到目标素数的最小步数. 解题报告:直接用最短路. 枚举1000-10000所有素数,如果素数A交换一位可以得到素 ...

  4. [并查集] POJ 1611 The Suspects

    The Suspects Time Limit: 1000MS   Memory Limit: 20000K Total Submissions: 35206   Accepted: 17097 De ...

  5. poj 1611 The Suspects(简单并查集)

    题目:http://poj.org/problem?id=1611 0号是病原,求多少人有可能感染 #include<stdio.h> #include<string.h> # ...

  6. 【原创】poj ----- 2376 Cleaning Shifts 解题报告

    题目地址: http://poj.org/problem?id=2376 题目内容: Cleaning Shifts Time Limit: 1000MS   Memory Limit: 65536K ...

  7. 【原创】poj ----- 2524 Ubiquitous Religions 解题报告

    题目地址: http://poj.org/problem?id=2524 题目内容: Ubiquitous Religions Time Limit: 5000MS   Memory Limit: 6 ...

  8. POJ - 1611 The Suspects 【并查集】

    题目链接 http://poj.org/problem?id=1611 题意 给出 n, m 有n个人 编号为 0 - n - 1 有m组人 他们之间是有关系的 编号为 0 的人是 有嫌疑的 然后和 ...

  9. [POJ 1002] 487-3279 C++解题报告

        487-3279 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 228365   Accepted: 39826 D ...

随机推荐

  1. 【转】从Go、Swift语言出发

    Google于2009年第一次提出了Go的构思,Facebook在去年春天引入了Hack,随后不久Apple也发布了其Swift语言. 在战争中,胜利者写历史书:在科技中,赢的公司都在写编程语言.互联 ...

  2. stl 迭代器(了解)

    STL 主要是由 containers(容器),iterators(迭代器)和 algorithms(算法)的 templates(模板)构成的. 对应于它们所支持的操作,共有五种 iterators ...

  3. configure: error: Please reinstall the libcurl distribution

    configure: error: Please reinstall the libcurl distribution - easy.h should be in /include/curl/ 基本上 ...

  4. 通过ajax访问aspx的CodeBehind中的方法

    引言 在项目中突然看到,aspx中的ajax可以访问aspx.cs中的方法,觉得很新奇,也许是lz少见多怪,不过,真的有发现新大陆似的那种兴奋,你也许知道这代表什么,学会了这种方式,代表你以后,可以建 ...

  5. Windows下Git Bash中文乱码

    文章转自:http://ideabean.iteye.com/blog/2007367 打开Git Bash 进入目录:$ cd /etc 1. 编辑 gitconfig 文件:$ vi gitcon ...

  6. mapreduce job提交流程源码级分析(一)(原创)

    首先,在自己写的MR程序中通过org.apache.hadoop.mapreduce.Job来创建Job.配置好之后通过waitForCompletion方法来提交Job并打印MR执行过程的log.H ...

  7. Charm Bracelet

    Charm Bracelet Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Subm ...

  8. 提高php运行效率的50个技巧

    1.如果能将类的方法定义成static,就尽量定义成static,它的速度会提升将近4倍. 2.并不是事必面向对象(OOP),面向对象往往开销很大,每个方法和对象调用都会消耗很多内存. 3.方法调用看 ...

  9. java笔记--枚举总结与详解

    由于工作原因,已经有两礼拜没有更新博客了,好不容易完成了工作项目,终于又可以在博客园上愉快的玩耍了. 嗯,今天下午梳理了一下关于java枚举的笔记,比较长,不过还是觉得挺厚实的,哈哈,有出入的地方,欢 ...

  10. FineUI第八天----下拉列表控件

    下拉列表控件 3.模拟树的下拉列表: 其他的控件都跟Asp.net的差不多.