并查集 (Union Find ) P - The Suspects
In the Not-Spreading-Your-Sickness University (NSYSU), there are many student groups.
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
A case with n = 0 and m = 0 indicates the end of the input, and need not be processed.
Output
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的更多相关文章
- POJ 1611 The Suspects 并查集 Union Find
本题也是个标准的并查集题解. 操作完并查集之后,就是要找和0节点在同一个集合的元素有多少. 注意这个操作,须要先找到0的父母节点.然后查找有多少个节点的额父母节点和0的父母节点同样. 这个时候须要对每 ...
- 并查集(Union/Find)模板及详解
概念: 并查集是一种非常精巧而实用的数据结构,它主要用于处理一些不相交集合的合并问题.一些常见的用途有求连通子图.求最小生成树的Kruskal 算法和求最近公共祖先等. 操作: 并查集的基本操作有两个 ...
- 并查集 (poj 1611 The Suspects)
原题链接:http://poj.org/problem?id=1611 简单记录下并查集的模板 #include <cstdio> #include <iostream> #i ...
- 并查集模板题(The Suspects )HZNU寒假集训
The Suspects Time Limit: 1000MS Memory Limit: 20000KTotal Submissions: 36817 Accepted: 17860 Descrip ...
- Java 并查集Union Find
对于一组数据,主要支持两种动作: union isConnected public interface UF { int getSize(); boolean isConnected(int p,in ...
- 【裸的并查集】POJ 1611 The Suspects
http://poj.org/problem?id=1611 [Accepted] #include<iostream> #include<cstdio> #include&l ...
- 最小生成树(Minimum Spanning Tree)——Prim算法与Kruskal算法+并查集
最小生成树——Minimum Spanning Tree,是图论中比较重要的模型,通常用于解决实际生活中的路径代价最小一类的问题.我们首先用通俗的语言解释它的定义: 对于有n个节点的有权无向连通图,寻 ...
- bzoj1854 [Scoi2010]游戏【构图 并查集】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1854 没想到怎么做真是不应该,看到每个武器都有两个属性,应该要想到连边构图的!太不应该了! ...
- [leetcode] 并查集(Ⅰ)
预备知识 并查集 (Union Set) 一种常见的应用是计算一个图中连通分量的个数.比如: a e / \ | b c f | | d g 上图的连通分量的个数为 2 . 并查集的主要思想是在每个连 ...
随机推荐
- IMP-00010: 不是有效的导出文件,标题验证失败
IMP-00010: 不是有效的导出文件,标题验证失败 IMP-00000: 未成功终止导入 在google上查找了一下,大概有两种情况: 1.imp/exp的版本不对,也就是说低版本的导出,可以 ...
- [JZOJ 5912] [NOIP2018模拟10.18] VanUSee 解题报告 (KMP+博弈)
题目链接: https://jzoj.net/senior/#contest/show/2530/2 题目: 众所周知,cqf童鞋对哲学有着深入的理解和认识,并常常将哲学思想应用在实际生活中,例如锻炼 ...
- SQL控制语句基础
SQL变量 全局变量: 全局变量是由系统定义和维护的使用两个@作为前缀,不能由用户声明和赋值! 常用的全局变量如下 @@version :获取当前使用的SQL Server版本号 EG: select ...
- js小知识colspan和rowspan
colspan和rowspan这两个属性用于合并表格的列或者行. colspan是"column span"(跨列)的缩写,所以colspan属性用在td标签中,用来跨列合并单元 ...
- 2019Pycharm激活方法
1.将“0.0.0.0 account.jetbrains.com”添加到hosts文件中 2.打开http://idea.lanyus.com/ 3.获取激活码,粘贴到第二个选项中 亲测可用.
- 虚拟机CentOS6.8下安装JDK
CentOS6.8下 首先下载JDK,执行命令如下: wget http://download.oracle.com/otn-pub/java/jdk/8u172-b11/a58eab1ec24242 ...
- javascript常用代码(不完整版)
求大神指点 Javascript嵌入式 <script typt:javascript>代码</script> 注释 //或者/*内容*/ 变量名赋值 Var 变量名 = 值 ...
- python的数据类型转换
#编码:#py3中只有2种数据类型:str , bytes# str: unicode形式# bytes: 16进制 (更底层) 有utf8,gbk,gb2312 等等类型 #s='hi 范' # 编 ...
- Linxu基本指令
一.Linux权限的概念 Linux下有两种用户:普通用户和超级用户(). 普通用户:在linux下做有限的事情: 超级用户:可以在linux系统下做任何事情,不受限制. 普通用户的提示符是“$”,超 ...
- Nginx 禁止 ip 访问
server { listen 80 default_server; server_name _; access_log /logs/ip-access.log main; error_log /lo ...