【并查集】POJ1611-The Suspects + 并查集简单理解

2023-12-15 22:39

本文主要是介绍【并查集】POJ1611-The Suspects + 并查集简单理解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

今天讲的新东西是并查集啦~因为以前看过一个特别好理解的介绍并查集的文章,所以今天还挺能理解的。。。推荐给大家,顺便我也做个马克。。。

链接:高级数据结构设计--并查集及实现学习笔记(有趣篇) - ACShiryu - 博客园 

另外里面也有一些相关的题,可以看一看!

其实要是光把部分的代码放上去看不懂还是并没有什么卵卵用,来道相对(没错就是相对)典型的简单的题吧!

来人,上题!


【题目】


The Suspects
Time Limit: 1000MS Memory Limit: 20000K
   

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

Asia Kaohsiung 2003

【题意】

就是说一个学校有很多社团,一天0号同学感染了SARS,而且和0号同学同在一个社团的人都会被感染,被感染的同学如果参加了其它社团,那么其他同学参加的社团所有成员都会被感染,以此类推,给你这个学校的社团成员名单,问共有多少同学被感染。

输入有若干测试实例,数据以n和m都为0时结束,第一行第一个数字n是该学校参加社团同学的总人数,第二个m表示有m个社团,下面m行第一个数字表示每个社团的人数,后面表示每个社团的成员学号。

输出占一行,输出被感染同学人数。


【思路】

之所以选这道题,是因为它能较独立地展现两个(三个?)并查集里面常用的函数或者说技巧。这道题说白了主要分为以下几步:把每个社团的成员分别铁索连环起来并统计社团人数,把有同一个同学参加的几个社团铁索连环并趁机统计总人数,找到0所在的社团,找到与0联动的最顶层同学编号,这位同学此时是所有被感染的同学的头头,此时只要将这位同学所对应的人数计数器显示出来就行了,这其中对应两个函数:find():用来查找最高的同学;Union():铁索连环社团成员/各个社团;另外要加一个num[]数组来实时记录总人数。具体还是要看代码中我的注释:


【代码】

#include<cstdio>int n,m,form,latt,a[30001],num[30001];//num数组用来记录社团人数,一开始没组社团时每个人自成一队每个人对应的num都是1,当有两个人合并时将两个人对应的num加起来 
void chongzhi();
int find(int x);
void Union(int p,int q);int main()
{while(scanf("%d%d",&n,&m)&&(n||m)){chongzhi();//重置数据 for(int i=0;i<m;i++){int nn;scanf("%d",&nn);for(int j=0;j<nn;j++){if(j==0){scanf("%d",&form);continue;}scanf("%d",&latt);//输入,每行第一个数表示成员个数 Union(form,latt);}}printf("%d\n",num[find(0)]);}
}void chongzhi()
{for(int i=0;i<=n;i++){a[i]=i;num[i]=1;}
}int find(int x)
{return a[x]==x?x:a[x]=find(a[x]);//查找根节点 
}void Union(int p,int q)
{int root1=find(p);int root2=find(q);if(root1!=root2){a[root2]=root1;//此时root1是老大 num[root1]+=num[root2];//把两个社团的人数合并为一个社团 }<span style="font-family: Arial, Helvetica, sans-serif;">}</span>


BilngBilng收工啦~


这篇关于【并查集】POJ1611-The Suspects + 并查集简单理解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/498158

相关文章

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu2289(简单二分)

虽说是简单二分,但是我还是wa死了  题意:已知圆台的体积,求高度 首先要知道圆台体积怎么求:设上下底的半径分别为r1,r2,高为h,V = PI*(r1*r1+r1*r2+r2*r2)*h/3 然后以h进行二分 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#includ

usaco 1.3 Prime Cryptarithm(简单哈希表暴搜剪枝)

思路: 1. 用一个 hash[ ] 数组存放输入的数字,令 hash[ tmp ]=1 。 2. 一个自定义函数 check( ) ,检查各位是否为输入的数字。 3. 暴搜。第一行数从 100到999,第二行数从 10到99。 4. 剪枝。 代码: /*ID: who jayLANG: C++TASK: crypt1*/#include<stdio.h>bool h

uva 10387 Billiard(简单几何)

题意是一个球从矩形的中点出发,告诉你小球与矩形两条边的碰撞次数与小球回到原点的时间,求小球出发时的角度和小球的速度。 简单的几何问题,小球每与竖边碰撞一次,向右扩展一个相同的矩形;每与横边碰撞一次,向上扩展一个相同的矩形。 可以发现,扩展矩形的路径和在当前矩形中的每一段路径相同,当小球回到出发点时,一条直线的路径刚好经过最后一个扩展矩形的中心点。 最后扩展的路径和横边竖边恰好组成一个直

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

poj 1113 凸包+简单几何计算

题意: 给N个平面上的点,现在要在离点外L米处建城墙,使得城墙把所有点都包含进去且城墙的长度最短。 解析: 韬哥出的某次训练赛上A出的第一道计算几何,算是大水题吧。 用convexhull算法把凸包求出来,然后加加减减就A了。 计算见下图: 好久没玩画图了啊好开心。 代码: #include <iostream>#include <cstdio>#inclu

uva 10130 简单背包

题意: 背包和 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>

poj 1182 并查集 食物链类

题意: 有n只动物,分别编号1....n。所有动物都属于A,B,C中的一种,已知A吃B,B吃C,C吃A。 按顺序给出下面两种共K条信息: 1. x 和 y 属于同一类。 2. x 吃 y 。 然而这些信息可能会出错,有可能有的信息和之前给出的信息矛盾,也有的信息可能给出的 x 和 y 不在n的范围内。 求k条信息中有多少条是不正确的。 解析: 对于每只动物,创建3个元素 i

【C++高阶】C++类型转换全攻略:深入理解并高效应用

📝个人主页🌹:Eternity._ ⏩收录专栏⏪:C++ “ 登神长阶 ” 🤡往期回顾🤡:C++ 智能指针 🌹🌹期待您的关注 🌹🌹 ❀C++的类型转换 📒1. C语言中的类型转换📚2. C++强制类型转换⛰️static_cast🌞reinterpret_cast⭐const_cast🍁dynamic_cast 📜3. C++强制类型转换的原因📝