poj 1611 The Suspects(第一道并查集)
题意:
有N个学生,编号为0-n-1,现在0号学生感染了非典,凡是和0在一个社团的人就会感染,
并且这些人如果还参加了别的社团,他所在的社团照样全部感染,社团个数为m,求感染的人数。
输入:
n代表人数,m代表社团数
社团的人数,第一个人编号,……
……
#include<stdio.h>
const int MAX=;
int n,m,k;
int parent[MAX+];
int total[MAX+];
//total[GetParent(a)] 是a所在的group的人数
int GetParent(int a)
{//获取a的根,并把a的父节点改为跟
if(parent[a]!=a)
parent[a]=GetParent(parent[a]);
return parent[a];
}
void Merge(int a,int b)
{
int p1=GetParent(a);
int p2=GetParent(b);
if(p1==p2)
return ;
total[p1]+=total[p2];
parent[p2]=p1;
}
int main()
{
int i,j;
while(true)
{
scanf("%d%d",&n,&m);
if(n==&&m==)break;
for(i=;i<n;i++)
{
parent[i]=i;
total[i]=;
}
for(i=;i<m;i++)
{
int h,s;
scanf("%d%d",&k,&h);
for(j=;j<k;j++)
{
scanf("%d",&s);
Merge(h,s);
}
}
printf("%d\n",total[GetParent()]);;
}
return ;
}
代码精炼版
摘自:Jack Ge for ACM
http://www.cnblogs.com/jackge/archive////.html
并查集学习:
l 并查集:(union-find sets)
一种简单的用途广泛的集合. 并查集是若干个不相交集合,能够实现较快的合并和判断元素所在集合的操作,应用很多,如其求无向图的连通分量个数等。最完美的应用当属:实现Kruskar算法求最小生成树。
l 并查集的精髓(即它的三种操作,结合实现代码模板进行理解):
1、MakeSet(x) 把每一个元素初始化为一个集合
初始化后每一个元素的父亲节点是它本身,每一个元素的祖先节点也是它本身(也可以根据情况而变)。
2、FindSet(x) 查找一个元素所在的集合
查找一个元素所在的集合,其精髓是找到这个元素所在集合的祖先!这个才是并查集判断和合并的最终依据。
判断两个元素是否属于同一集合,只要看他们所在集合的祖先是否相同即可。
合并两个集合,也是使一个集合的祖先成为另一个集合的祖先,具体见示意图
3、Union(x,y) 合并x,y所在的两个集合
合并两个不相交集合操作很简单:
利用Find_Set找到其中两个集合的祖先,将一个集合的祖先指向另一个集合的祖先。如图

l 并查集的优化
路径压缩
FindSet(x)寻找祖先时我们一般采用递归查找,但是当元素很多亦或是整棵树变为一条链时,每次Find_Set(x)都是O(n)的复杂度,有没有办法减小这个复杂度呢?
答案是肯定的,这就是路径压缩,即当我们经过"递推"找到祖先节点后,"回溯"的时候顺便将它的子孙节点都直接指向祖先,这样以后再次Find_Set(x)时复杂度就变成O(1)了,Union(x,y)
即合并的时候将元素少的集合合并到元素多的集合中,这样合并之后树的高度会相对较小。路径压缩方便了以后的查找。

#include<stdio.h>
const int maxn=;
int father[maxn];
int total[maxn];
void MakeSet(int n)
{
for(int i=; i<n; i++)
{
father[i]=i;
total[i]=;
}
}
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(total[x]>=total[y])
{
father[y]=x;
total[x]+=total[y];
}
else
{
father[x]=y;
total[y]+=total[x];
}
}
int main()
{
int n,m;
while(scanf("%d %d",&n,&m)!=EOF)
{
if(n==&&m==)
break;
int k,a,b;
MakeSet(n);
while(m--)
{
scanf("%d %d",&k,&a);
for(int i=; i<k; i++)
{
scanf("%d",&b);
Union(a,b);
}
}
printf("%d\n",total[father[]]);
}
return ;
}
poj 1611 The Suspects(第一道并查集)的更多相关文章
- poj 1611 :The Suspects经典的并查集题目
Severe acute respiratory syndrome (SARS), an atypical pneumonia of unknown aetiology, was recognized ...
- POJ 1611 The Suspects(简单并查集)
( ̄▽ ̄)" #include<iostream> #include<cstdio> using namespace std; ]; void makeSet(int ...
- 【POJ】The Suspects(裸并查集)
并查集的模板题,为了避免麻烦,合并的时候根节点大的合并到小的结点. #include<cstdio> #include<algorithm> using namespace s ...
- FJUT寒假作业第三周数蚂蚁(记录第一道并查集)
http://210.34.193.66:8080/vj/Contest.jsp?cid=162#P7 思路:用并查集合并集合,最后遍历,找到集合的根的个数. 并查集是森林,森林中的每一颗树是一个集合 ...
- POJ 1611 The Suspects (并查集)
The Suspects 题目链接: http://acm.hust.edu.cn/vjudge/contest/123393#problem/B Description 严重急性呼吸系统综合症( S ...
- poj 1611 The Suspects 并查集变形题目
The Suspects Time Limit: 1000MS Memory Limit: 20000K Total Submissions: 20596 Accepted: 9998 D ...
- POJ 1611 The Suspects (并查集求数量)
Description Severe acute respiratory syndrome (SARS), an atypical pneumonia of unknown aetiology, wa ...
- 并查集 (poj 1611 The Suspects)
原题链接:http://poj.org/problem?id=1611 简单记录下并查集的模板 #include <cstdio> #include <iostream> #i ...
- [并查集] POJ 1611 The Suspects
The Suspects Time Limit: 1000MS Memory Limit: 20000K Total Submissions: 35206 Accepted: 17097 De ...
随机推荐
- z变换的性质
z变换的许多重要性质在数字信号处理中常常要用到. 序列 z变换 收敛域 1)x(n) X(z) Rx-< |z| <Rx+ 2)y(n) Y(z) Ry-< |z| <Ry+ ...
- [BZOJ]4034: [HAOI2015]树上操作
[HAOI2015]树上操作 传送门 题目大意:三个操作 1:a,b,c b节点权值+c 2:a,b,c 以b为根的子树节点权值全部+c 3:a,b 查询b到根路径的权值和. 题解:树链剖分 操作1 ...
- 在vue项目中正确的引入jquery和bootstrap
<script>标签引入jquery在vue脚手架里并不适用,需要利用webpack引入jquery 一.第一种方法 1:因为已经安装了vue脚手架,所以需要在webpack中全局引入jq ...
- manyToManyField理解和用法
转:http://www.cnblogs.com/linxiyue/p/3667418.html
- ①HttpURLConnection通过报文提交
在进行短信发送的接口,因厂家不同,有的厂家会采用报文的格式进行短信请求的发送与接收.本文主要介绍利用HttpURLConnection进行短信报文的请求与响应. 一般的url请求分为两种,一种是GET ...
- css控制div下图片自适应解决方法:图片不超过最大宽度
我们(特别是像我一样的菜鸟)经常会遇到一个问题——图片自适应.这个问题是很普遍的.在文章区,在论坛,可以这么说:哪儿需要上传图片,哪儿就存在这个问题,而论坛上也不时有人询问.为什么?原因很简单,我们不 ...
- ubuntu 环境变量配置
1.vim /etc/environment 2.vim /etc/profile export JAVA_HOME=/opt/jdk1.6.0_45PATH=$JAVA_HOME/bin:/pub/ ...
- java代码=--数组复制
总结:arraycopy注意数组定义的长度.不足会补0 package clientFrame; //数组的复制arraycopy() public class Xiang { public stat ...
- spring+hibernate ---含AOP--事务--laobai
biz包: package com.etc.biz; import java.util.List; import org.springframework.orm.hibernate3.support. ...
- in not in 和 null , in 判断范围中可以包含null,而not in判断不能包括null
oracle中,任何字符串与null比较得到的结果都是null,而 oracle的判断条件为null时就退出判断(?) 因此判断某个字符串是否在一个集合中时,not in 和 in的结果完全不一样,如 ...