Severe acute respiratory syndrome (SARS), an atypical pneumonia of unknown aetiology, was recognized as a global threat in mid-March 2003.
To minimize transmission to others, the best strategy is to separate the suspects from others. 
In the Not-Spreading-Your-Sickness University (NSYSU), there are many student groups.
Students in the same group intercommunicate with each other frequently, and a student may join several groups.
To prevent the possible transmissions of SARS, the NSYSU collects the member lists of all student groups, and makes the following rule in their standard operation procedure (SOP). 
Once a member in a group is a suspect, all members in the group are suspects. 
However, they find that it is not easy to identify all the suspects when a student is recognized as a suspect. Your job is to write a program which finds all the suspects.

Input

The input file contains several cases. Each test case begins with two integers n and m in a line, where n is the number of students, and m is the number of groups.
You may assume that 0 < n <= 30000 and 0 <= m <= 500. Every student is numbered by a unique integer between 0 and n−1,=and initially student 0 is recognized as a suspect in all the cases.
This line is followed by m member lists of the groups, one line per group. Each line begins with an integer k by itself representing the number of members in the group.
Following the number of members, there are k integers representing the students in this group. All the integers in a line are separated by at least one space. 
A case with n = 0 and m = 0 indicates the end of the input, and need not be processed.

Output

For each case, output the number of suspects in one line.

Sample Input

100 4
2 1 2
5 10 13 11 12 14
2 0 1
2 99 2
200 2
1 5
5 1 2 3 4 5
1 0
0 0

Sample Output

4
1
1 题目大意:
为了防止非典的进一步传播,要你写一个程序,通过已知的学生群体中的患者,找出所有患者,所有的学生都是怀疑对象。
每个案例,第一行 n(学生数量) m(表示有m组数据),接下来便是m组数据,每一组数据表示同组人的个数及其编号,同组的人才能被传染,0为传染源。
output:最多能被传染的人数、 方法:并查集
AC代码:
#include<iostream>
#define maxn 30005
using namespace std;
int p[maxn];
int jishu[maxn];
int fa;
int findx(int x)
{
int temp=x;
return x==p[x]?x,p[temp]=x:findx(p[x]);
}
int myunion(int son, int fa){
int s=findx(son),f=findx(fa);
if(s!=f){
p[s]=f;
jishu[f]+=jishu[s];
}
return ;
}
int main ()
{
int n,m,t;
while(cin>>n>>m&&(n+m)!=)
{
for(int i=;i<=n;i++)
{
p[i]=i;
jishu[i]=;
}
while(m--)
{
int num;
cin>>t;
for(int i=;i<t;i++)
{
cin>>num;
if(i) myunion(num,fa);
fa=num;
}
}
cout<<jishu[findx()]<<endl;;
}
}

这个真的很难理解!

首先

100 4
2 1 2
5 10 13 11 12 14
2 0 1
2 99 2
将每一组数据写成一棵树,若有交叉出现,便合并成一棵树
即:用一个数组,先初始化为a【i】=i,然后将同一组数用父子关系联系起来,即 a【son】=father,形成一棵单独的树。
例如:第一组把1作为根,即father,即a【1】=1不变,a【2】=1,即 a【son】=father,第二,三组以此类推。
但是要注意的是,当出现已经有过父子关系的节点时,要分情况讨论。
例如:第一组的1,已经作为2的father,第三组又出现1,作为0的son.这个时候我们不能单纯的写成两棵独立的树,便要合并union。
方法:判断并合并
int myunion(int son, int fa){
int s=findx(son),f=findx(fa); //找到祖宗
if(s!=f){ //判断祖宗是否一致,一致根本就不用管
p[s]=f; //不一致便合并,串起来
jishu[f]+=jishu[s];
}
return ;
}

例如:

第一组之后:p【1】=1,p【2】=1

第三组之后:p【0】=0,p【1】=0,p【2】=0(调用了findx函数,进行了路径压缩)

第四组之后:p【0】=99,p【2】=0,p【99】=99


并查集 (Union Find ) P - The Suspects的更多相关文章

  1. POJ 1611 The Suspects 并查集 Union Find

    本题也是个标准的并查集题解. 操作完并查集之后,就是要找和0节点在同一个集合的元素有多少. 注意这个操作,须要先找到0的父母节点.然后查找有多少个节点的额父母节点和0的父母节点同样. 这个时候须要对每 ...

  2. 并查集(Union/Find)模板及详解

    概念: 并查集是一种非常精巧而实用的数据结构,它主要用于处理一些不相交集合的合并问题.一些常见的用途有求连通子图.求最小生成树的Kruskal 算法和求最近公共祖先等. 操作: 并查集的基本操作有两个 ...

  3. 并查集 (poj 1611 The Suspects)

    原题链接:http://poj.org/problem?id=1611 简单记录下并查集的模板 #include <cstdio> #include <iostream> #i ...

  4. 并查集模板题(The Suspects )HZNU寒假集训

    The Suspects Time Limit: 1000MS Memory Limit: 20000KTotal Submissions: 36817 Accepted: 17860 Descrip ...

  5. Java 并查集Union Find

    对于一组数据,主要支持两种动作: union isConnected public interface UF { int getSize(); boolean isConnected(int p,in ...

  6. 【裸的并查集】POJ 1611 The Suspects

    http://poj.org/problem?id=1611 [Accepted] #include<iostream> #include<cstdio> #include&l ...

  7. 最小生成树(Minimum Spanning Tree)——Prim算法与Kruskal算法+并查集

    最小生成树——Minimum Spanning Tree,是图论中比较重要的模型,通常用于解决实际生活中的路径代价最小一类的问题.我们首先用通俗的语言解释它的定义: 对于有n个节点的有权无向连通图,寻 ...

  8. bzoj1854 [Scoi2010]游戏【构图 并查集】

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1854 没想到怎么做真是不应该,看到每个武器都有两个属性,应该要想到连边构图的!太不应该了! ...

  9. [leetcode] 并查集(Ⅰ)

    预备知识 并查集 (Union Set) 一种常见的应用是计算一个图中连通分量的个数.比如: a e / \ | b c f | | d g 上图的连通分量的个数为 2 . 并查集的主要思想是在每个连 ...

随机推荐

  1. 如何从 Datagrid 中获得单元格的内容与 使用值转换器进行绑定数据的转换IValueConverter

    一.如何从 Datagrid 中获得单元格的内容 DataGrid 属于一种 ItemsControl, 因此,它有 Items 属性并且用ItemContainer 封装它的 items. 但是,W ...

  2. 服务器共享session的方式

    服务器共享session的方式 简介 1. 基于NFS的Session共享 NFS是Net FileSystem的简称,最早由Sun公司为解决Unix网络主机间的目录共享而研发.这个方案实现最为简单, ...

  3. NVMe到底是什么?

    转:http://www.expreview.com/42142.html 有关注SSD的朋友应该今年听到NVMe这个词的频率应该不低,随着高端SSD的战场已经抛弃SATA向PCI-E转移,老旧的AH ...

  4. HDU 1856 More is better【并查集】

    解题思路:将给出的男孩的关系合并后,另用一个数组a记录以find(i)为根节点的元素的个数,最后找出数组a的最大值 More is better Time Limit: 5000/1000 MS (J ...

  5. unserialize反序列化错误的解决办法

    1. UTF-8编码解决反序列化出错问题 function mb_unserialize($serial_str) { $serial_str = str_replace("\r" ...

  6. LNMP升级开启TLSv1.3支持

    LNMP升级开启TLSv1.3支持 TLSv1.3版本的优势:https://baijiahao.baidu.com/s?id=1611365293186683991&wfr=spider&a ...

  7. [Vijos P1369]难解的问题

    题目大意:给你一个序列,叫你求最长上升子序列长度,但必须包含第k项. 解题思路:我们把k左边的比a[k]大的数去掉,k右边的比k小的数去掉,就可以保证选到a[k]了(因为左边的数小于a[k],而a[k ...

  8. k8s日志收集配置

    容器日志样例 172.101.32.1 - - [03/Jun/2019:17:14:10 +0800] "POST /ajaxVideoQueues!queryAllUser.action ...

  9. linux磁盘管理与分区 转载

    原文:http://zhengjianglong.leanote.com/post/linux%E7%A3%81%E7%9B%98%E5%88%86%E5%8C%BA 一.基础知识 一块磁盘可以分为多 ...

  10. 2015 Multi-University Training Contest 2 Buildings

    Buildings Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total ...