实用数据结构---并查集

题目描述 Description

若某个家族人员过于庞大,要判断两个是否是亲戚,确实还很不容易,现在给出某个亲戚关系图,求任意给出的两个人是否具有亲戚关系。 规定:x和y是亲戚,y和z是亲戚,那么x和z也是亲戚。如果x,y是亲戚,那么x的亲戚都是y的亲戚,y的亲戚也都是x的亲戚。

输入描述 Input Description

第一行:三个整数n,m,p,(n<=5000,m<=5000,p<=5000),分别表示有n个人,m个亲戚关系,询问p对亲戚关系。 以下m行:每行两个数Mi,Mj,1<=Mi,Mj<=N,表示Ai和Bi具有亲戚关系。 接下来p行:每行两个数Pi,Pj,询问Pi和Pj是否具有亲戚关系。

输出描述 Output Description

P行,每行一个’Yes’或’No’。表示第i个询问的答案为“具有”或“不具有”亲戚关系。

样例输入 Sample Input

6 5 3

1 2

1 5

3 4

5 2

1 3

1 4

2 3

5 6

样例输出 Sample Output

Yes

Yes

No

数据范围及提示 Data Size & Hint

n<=5000,m<=5000,p<=5000

这里我们以这道题来讲并查集,引用一下百度百科的描述:在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中。这一类问题近几年来反复出现在信息学的国际国内赛题中,其特点是看似并不复杂,但数据量极大,若用正常的数据结构来描述的话,往往在空间上过大,计算机无法承受;即使在空间上勉强通过,运行的时间复杂度也极高,根本就不可能在比赛规定的运行时间(1~3秒)内计算出试题需要的结果,只能用并查集来描述。

这题我们把有亲戚关系的人放入一个集合,然后根据数据给出的点,如果两个点在一个集合,则说明两人又亲戚关系。

在建立这个亲戚关系的集合时我们用到了图的联通分量的维护,对于给出亲戚关系并且没在同一集合的点加入一个集合,

注意在查询时用到了路径压缩

#include<stdio.h>
#include<string.h>
#define N 5005
int pa[N];
int find(int x){
	return pa[x] == x ? x : find(pa[x]);
}
int main(){
	int n, m, p;
	scanf("%d%d%d", &n, &m, &p);
	int i, a, b;
	for (i = 0; i <= n; i++)
		pa[i] = i;
	for (i = 0; i < m; i++){
		scanf("%d%d", &a, &b);
		a = find(a);
		b = find(b);
		if (a != b)
			pa[a] = b;
	}
	for (i = 0; i < p; i++){
		scanf("%d%d", &a, &b);
		if (find(a) == find(b))
			printf("Yes\n");
		else printf("No\n");
	}
	return 0;
}
时间: 2024-10-12 20:18:12

实用数据结构---并查集的相关文章

POJ 1984 Navigation Nightmare (数据结构-并查集)

Navigation Nightmare Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 4072   Accepted: 1615 Case Time Limit: 1000MS Description Farmer John's pastoral neighborhood has N farms (2 <= N <= 40,000), usually numbered/labeled 1..N. A series o

POJ 1703 Find them, Catch them(数据结构-并查集)

Find them, Catch them Description The police office in Tadu City decides to say ends to the chaos, as launch actions to root up the TWO gangs in the city, Gang Dragon and Gang Snake. However, the police first needs to identify which gang a criminal b

读书笔记 之 数据结构(并查集详解)(POJ1703)

<ACM/ICPC算法训练教程>读书笔记-这一次补上并查集的部分.将对并查集的思想进行详细阐述,并附上本人AC掉POJ1703的Code. 在一些有N个元素的集合应用问题中,通常会将每个元素构成单元素集合,然后按照一定顺序将同属一组的集合合并,期间要反复查找每一个元素在哪个集合中.这类问题往往看似简单,但是数据量很大,因此容易造成TLE或MLE,也就是空间度和时间度极其复杂.因此在这里,我们引入一种抽象的特殊数据结构——并查集. 并查集:类似一个族谱,每个结点均有一个father[x]来表示x

HDU 1988 Cube Stacking (数据结构-并查集)

Cube Stacking Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 18900   Accepted: 6568 Case Time Limit: 1000MS Description Farmer John and Betsy are playing a game with N (1 <= N <= 30,000)identical cubes labeled 1 through N. They start w

数据结构---并查集

并查集,顾名思义,合并 查找 集合: 并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题.常常在使用中以森林来表示. 对于概念等等的这里不再赘述,直接讲解应用. [初始化] MakeSet,将每一个节点的父节点置为本身:rank(秩),是节点构成树的深度 void MakeSet(){ for(int i=1;i<=maxn;i++){ parent[i].value = i; parent[i].rank=0; } } [查找] 一直向上查找,直到

数据结构--并查集的原理及实现

一,并查集的介绍 并查集(Union/Find)从名字可以看出,主要涉及两种基本操作:合并和查找.这说明,初始时并查集中的元素是不相交的,经过一系列的基本操作(Union),最终合并成一个大的集合. 而在某次合并之后,有一种合理的需求:某两个元素是否已经处在同一个集合中了?因此就需要Find操作. 并查集是一种 不相交集合 的数据结构,设有一个动态集合S={s1,s2,s3,.....sn},每个集合通过一个代表来标识,该代表中集合中的某个元素. 比如,若某个元素 x 是否在集合 s1 中(Fi

数据结构——并查集

一.并查集的定义 并查集是一种维护集合的数据结构,它的名字中"并""查""集"分别取自 Union(合并).Find(查找).Set(集合)这 3 个单词.也就是说,并查集支持下面两个操纵: 合并:合并两个集合. 查找:判断两个元素是否在一个集合. 并查集的实现就是用一个数组: int father[N]; // 表示元素的父亲结点 例如 father[1]=2 就表示元素 1 的父亲结点是元素 2.另外,如果 father[i]==i,则说明元

hdu 4056 Draw a Mess(数据结构-并查集)

Draw a Mess Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 864    Accepted Submission(s): 180 Problem Description It's graduated season, every students should leave something on the wall, so.

图论&amp;数据结构——并查集

Wikioi 4246 NOIP模拟赛Day2T1 奶牛的身高  题目描述 Description 奶牛们在FJ的养育下茁壮成长.这天,FJ给了奶牛Bessie一个任务,去看看每个奶牛场中若干只奶牛的身高,由于Bessie是只奶牛,无法直接看出第i只奶牛的身高,而只能看出第i只奶牛与第j只奶牛的身高差,其中第i 只奶牛与第j只奶牛的身高差为A(i<=n).当A大于0时表示这只奶牛比前一只奶牛高A cm,小于0时则是低.现在,FJ让Bessie总共去看了m次身高,当然也就传回给FJ m对奶牛的身高