您的位置:首页 > 其它

并查集----The Suspects

2017-01-21 23:41 211 查看
并查集是将一些数据进行合并操作,一开始的时候每个人都是单独独立的,然后根据条件,进行合并,合并后会有些元素的根不再是自己了,同时多棵树也会根据要求变成一棵树,在完成这些条件后,就可以完成问题中的查询得到结果
关键点如下:
1.存在一个数组per[]用来存储每个元素的根,切记每次要进行初始化,初始化的要求是每个元素的初始化的根是自己
//根和高度的初始化
for (i = 0; i < n; i++)
{
p[i] = i;
r[i] = 0;
}
//寻找该元素的跟
int find(int i)
{
if (p[i] == i)
{
return i;
}
else
{
return find(p[i]);
}
}
2.用一个数组rank[]来存储该树的长度,当多棵树进行合并的时候,为了能够提高速度和效率,会把rank[]小的转移到rank[]大的上面,但是原来的rank[]不改变
//两个根的合并
void unite(int x, int y)
{
int u, v;
u = find(x);
v = find(y);
if (r[u] < r[v])
{
p[u] = v;
}
else
{
p[v] = u;
if (r[u] == r[v])
{
r[u]++;
}
}

3.查询
z = find(0);
for (i = 1; i < n; i++)
{
if (z == find(i))
{
sum++;
}
}
解题思路:
这道题是一道标准的并查集的题,我的思路是把每组的第一个当作这组的根,然后在m个小组循环之后,查找per[0]是几,也就是0号嫌疑人的根是谁,查到后开始遍历整个数组,由于数组n不大于30000,所以不会出现爆的可能,遍历每个数组的根是否跟0号嫌疑人的相同,相同的话算一个
总结起来就是:
1.初始化根,使得每个元素的初始根都是自己
2.随着循环更新rank[]的值,也就是树的高度,以此在进行树与树的合并时,能够将小的往大的连边,提高效率
3.查找最初嫌疑人0号的根,然后遍历数组中与0号跟相同的个数

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


题目大意:在n个学生中有一种病会传染,其中0号是已经患病的嫌疑人,然后有m个小组进行沟通,要是小组内有嫌疑人,那么这个小组的人都会患病,问一共有多少人患病

数据范围:0 < n <= 30000 and 0 <= m <= 500

涉及算法:并查集
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: