# 并查集

The Suspects
 Time Limit: 1000MS Memory Limit: 20000K Total Submissions: 17242 Accepted: 8319

Description

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

Source

并查集学习：

l         并查集：(union-find sets)

l         并查集的精髓（即它的三种操作，结合实现代码模板进行理解）：

1、Make_Set(x) 把每一个元素初始化为一个集合

2、Find_Set(x) 查找一个元素所在的集合

3、Union(x,y) 合并x,y所在的两个集合

l         并查集的优化

1、Find_Set(x)时 路径压缩

2、Union(x,y)时 按秩合并

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

const int maxn=30010;

int n,m;
int father[maxn];
int rank[maxn];

void makeSet(){
for(int i=0;i<n;i++){
father[i]=i;
rank[i]=1;
}
}

int findSet(int x){
if(x!=father[x]){
father[x]=findSet(father[x]);
}
return father[x];
}

void Union(int a,int b){
int x=findSet(a);
int y=findSet(b);
if(x==y)
return ;
if(rank[x]>=rank[y]){
father[y]=x;
rank[x]+=rank[y];
}else{
father[x]=y;
rank[y]+=rank[x];
}
}

int main(){

//freopen("input.txt","r",stdin);

while(~scanf("%d%d",&n,&m)){
if(n==0 && m==0)
break;
int k,a,b;
makeSet();
while(m--){
scanf("%d%d",&k,&a);
for(int i=1;i<k;i++){
scanf("%d",&b);
Union(a,b);
}
}
printf("%d\n",rank[father[0]]);
}
return 0;
}
• 本文已收录于以下专栏：

## 使用STL实现并查集

• lhrsdl
• 2014年07月25日 15:43
• 1674

## 【并查集专题】【HDU】

How Many Tables Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...
• zy691357966
• 2014年11月29日 18:34
• 2254

## 并查集 -- 学习详解

• JDPlus
• 2014年02月19日 16:50
• 3858

## 并查集详解 ——图文解说,简单易懂(转)

• liujian20150808
• 2016年03月10日 17:38
• 2417

## 并查集的简介及其C/C++代码的实现及优化

• Aiphis
• 2015年09月02日 20:03
• 363

## 图—并查集（解决朋友圈问题）

• ttyue_123
• 2016年08月09日 21:44
• 617

## 关系性并查集

• qq_36908995
• 2017年02月25日 23:00
• 373

## 并查集的分析及应用

• IAccepted
• 2014年01月27日 21:34
• 3300

## PAT 朋友圈（改）并查集统计集合中最大元素数目和统计集合数目

• wangwei6125
• 2017年04月02日 21:45
• 520

## ACM-数据结构-并查集

ACM竞赛中，并查集（DisjointSets）这个数据结构经常使用。顾名思义，并查集即表示集合，并且支持快速查找、合并操作。 并查集如何表示一个集合？它借助树的思想，将一个集合看成一棵有根树。那又如...
• u011787119
• 2015年07月10日 20:53
• 1002

举报原因： 您举报文章：并查集 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)