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

并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。常常在使用中以森林来表示。

摘自网络↑

下面主要是自己的感悟emm可能有些不对的地方欢迎指出

并查集,顾名思义,方便的主要就是合并和查询两种基本操作,然后说一下并查集的基本操作:

fa[i]表示点i的父节点,根节点的父节点是它自己。

这里就涉及到初始化,因为开始的时候每一个点都是一棵独立的树,它们都是根节点,所以它们要把fa[i]=i。

另外sz[i]表示这一棵树的深度,只有根节点的sz值才是有效的,可能有些题目里不会涉及但是还是打上来哈

void init()
{
for(int i=1;i<=n;i++)
{
fa[i]=i;
sz[i]=1;
}
}

合并:

在实现合并操作之前, 我们先要想一个问题:合并两棵树,是不是把这两棵树上任意两个节点产生联系就可以了?

很明显不是。

我们的合并操作,应该是要把其中一整棵树都挂在另一棵树的根节点上,也就是把a树的根节点的父节点设置为b树的根节点,就完成了a,b两树的合并。

所以现在的问题是取根节点。

初始写法:

int get(int x)
{
if(fa[x]==x)
return x;
return get(fa[x]);
}

但是!如果这么写,每次查找根节点都要花费太多的时间,如果题目特殊构造一条链型的树,那么就会出现TLE.

怎么优化呢?

其实,在每次查找根节点所途径的路上遇到的所有节点,我们都可以把它们直接挂到根节点上,这样下次查找的时候就会方便许多了。

最终写法:

int get(int x)
{
if(fa[x]==x)
return x;
int r=get(fa[x]);
fa[x]=r;
return r;
}

那么接下来才是实现合并的操作。

所谓合并,就是如上所述,把其中一棵树的根节点挂到另一棵树的根节点上,实现合并,那么就很容易实现:

void merge(int x,int y)
{
int r1=get(x);
int r2=get(y);
if(r1==r2)
return;
fa[r1]=r2;
sz[r2]+=sz[r1];
}

sz数组的变化请自行理解(绝对不是懒得写 )

下一个,查找。

查找其实很简单,就是看两个节点的根节点是否相同,如果一样,那么就是在同一棵树上,否则就不是:

bool ask(int x,int y)
{
if(get(x)==get(y))return true;
else return false;
}

下面贴上完整代码:

#include<bits/stdc++.h>
using namespace std;
int n,fa[10001],z,x,y,m,sz[10001];
void init()
{
for(int i=1;i<=n;i++)
{
fa[i]=i;
sz[i]=1;
}
}
int get(int x)
{
if(fa[x]==x)
return x;
int r=get(fa[x]);
fa[x]=r;
return r;
}
void merge(int x,int y)
{
int r1=get(x);
int r2=get(y);
if(r1==r2)
return;
fa[r1]=r2;
sz[r2]+=sz[r1];
}
bool ask(int x,int y)
{
if(get(x)==get(y))return true;
else return false;
}
int main()
{
cin>>n>>m;
int fa[n];
init();
for(int i=1;i<=m;i++)
{
cin>>z>>x>>y;
if(z==1)
{
merge(x,y);
}
else
if(ask(x,y))cout<<"Y"<<endl;
else cout<<"N"<<endl;
}
return 0;
}

ov.

【基本数据结构】并查集-C++的更多相关文章

  1. 算法手记 之 数据结构(并查集详解)(POJ1703)

    <ACM/ICPC算法训练教程>读书笔记-这一次补上并查集的部分.将对并查集的思想进行详细阐述,并附上本人AC掉POJ1703的Code. 在一些有N个元素的集合应用问题中,通常会将每个元 ...

  2. ACM数据结构-并查集

    ACM数据结构-并查集   并查集,在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合 ...

  3. 图论&数据结构——并查集

    Wikioi 4246 NOIP模拟赛Day2T1 奶牛的身高  题目描述 Description 奶牛们在FJ的养育下茁壮成长.这天,FJ给了奶牛Bessie一个任务,去看看每个奶牛场中若干只奶牛的 ...

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

    Find them, Catch them Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 31102   Accepted: ...

  5. 《挑战程序设计竞赛》2.4 数据结构-并查集 POJ1182 2236 1703 AOJ2170

    POJ1182 http://poj.org/problem?id=1182 题目 难得的中文题... 食物链 Time Limit: 1000MS Memory Limit: 10000K Tota ...

  6. 第三十一篇 玩转数据结构——并查集(Union Find)

    1.. 并查集的应用场景 查看"网络"中节点的连接状态,这里的网络是广义上的网络 数学中的集合类的实现   2.. 并查集所支持的操作 对于一组数据,并查集主要支持两种操作:合并两 ...

  7. 【题解】P2024 [NOI2001]食物链 - 数据结构 - 并查集

    P2024 [NOI2001]食物链 声明:本博客所有题解都参照了网络资料或其他博客,仅为博主想加深理解而写,如有疑问欢迎与博主讨论✧。٩(ˊᗜˋ)و✧*。 题目描述 动物王国中有三类动物 \(A,B ...

  8. <数据结构>并查集与树

    作用 查:给定一个元素,查询它在哪个集合内 并:合并两个元素所在的集合 实现思路 对应关系 元素-->结点 集合-->树 多个集合-->森林 用树的根节点作为不同树的标志 合并时只需 ...

  9. 数据结构(并查集):COGS 260. [NOI2002] 银河英雄传说

    260. [NOI2002] 银河英雄传说 ★★☆   输入文件:galaxy.in   输出文件:galaxy.out   简单对比时间限制:5 s   内存限制:128 MB [问题描述] 公元五 ...

  10. hiho1515 - 数据结构 并查集

    题目链接 小Hi的学校总共有N名学生,编号1-N.学校刚刚进行了一场全校的古诗文水平测验. 学校没有公布测验的成绩,所以小Hi只能得到一些小道消息,例如X号同学的分数比Y号同学的分数高S分. 小Hi想 ...

随机推荐

  1. MessageBox用法大全

    //1.显示提示信息 MessageBox.Show("Hello World!"); //2.给消息框加上标题 MessageBox.Show("Hello World ...

  2. List<T>多字段排序的一个通用类

    本文中的方法旨在解决通用的问题,非常注重效率的地方,还应该针对具体的类去写排序方法. 废话不多说,直接上代码 具体使用场景: 要排序的类 1 public class bb 2 { 3 public ...

  3. 用Delphi实现文件下载的几种方法(三种使用控件的方法)

    有个API就是UrlDownloadToFile.不仅如此,Delphi的一些控件也可以轻松实现下载,如NMHTTP,指定NMHTTP1.InputFileMode := ture; 指定Body为本 ...

  4. Qt 跨UI线程的数据交换和信号-槽调用实现方案汇总

    一.目录 转载1: http://my.oschina.NET/fanhuazi/blog/737224?ref=myread 点击打开链接 转载2: http://www.qtcn.org/bbs/ ...

  5. qt 维护x86和arm两套编译环境

    1.中间库: 中间库都放在middlewares目录,include头文件相同,所以不需要特殊处理,只要特殊处理lib安装目录, 示例pro文件如下: TEMPLATE = lib TARGET = ...

  6. Using VNC on a debian/Ubuntu server with a OS X Mac

    I got a brand new MacBook Pro 13" 2016. I used to work on GNU/Linux for decades. I don't want t ...

  7. 条款16:成对使用new和delete时要使用相同的形式

    请牢记: 如果在new表达式中使用[],必须在相应的delete表达式中也使用[]. new[]  对应  delete[] 如歌在new表达式中不适用[],一定不要在相应的delete表达式中使用[ ...

  8. Matlab与.Net混合编程-多维数组赋值出错的问题

    问题描述:Matlab可编译供.net调用的dll.两种不同环境对数据类型的定义相差较大,因此在C#中调用Matlab编译的函数时,首先要将C#中的变量类型转换成与Matlab对应的中转类型.Matl ...

  9. java多线程之线程安全

    线程安全和非线程安全是多线程的经典问题,非线程安全会在多个线程对同一个对象并发访问时发生. 注意1: 非线程安全的问题存在于实例变量中,如果是方法内部的私有变量,则不存在非线程安全问题. 实例变量是对 ...

  10. CSS样式规范

    一般团队都有对CSS样式的规范,因为只有写的规范些,维护层本低,易懂.我们开发并不一次性的,往往都是要迭代的,如果这次随便写,下次迭代的时候将付出高昂的代价.而团队的规范一般都大同小异,往往都包含一下 ...