并查集

题目

今天是伊格那丢的生日。他邀请了很多朋友。现在该吃晚饭了。伊格那丢想知道他至少需要多少张桌子。你必须注意到并不是所有的朋友都认识对方,而且所有的朋友都不想和陌生人待在一起。这个问题的一个重要规则是如果我告诉你A认识B, B认识C,这意味着A, B, C互相认识,所以它们可以在一个表中。例如:如果我告诉你A知道B, B知道C, D知道E,那么A, B, C可以在一个表中,D, E必须在另一个表中。伊格那丢至少需要两张表。输入以一个整数T(1<=T<=25)开始,它表示测试用例的数量。然后是T测试用例。每个测试用例都以两个整数N和M开始(1<=N,M<=1000)。N表示朋友的数量,朋友的数量从1到N进行标记,然后是M行。每一行由两个整数A和B(A!=B)组成,这意味着朋友A和朋友B互相认识。两种情况之间会有一条空行。对于每个测试用例,只输出Ignatius至少需要多少个表。不要打印任何空格。

运行代码

#include<iostream>
using namespace std;
int pre[1004];//有1000人
int t,n,m;//测试个数,n个人,M对
int finds(int x)//查找X是谁的friend
{
if(pre[x]==x)//如果是根节点
return x;
else
return pre[x]=finds(pre[x]);//查找上级
}
void mix(int x,int y)
{
int fx=finds(x);//查找X的根节点
int fy=finds(y);//查找Y的根节点
if(fx!=fy)
pre[fx]=fy;
}
int main()
{
cin>>t;//
while(t--)//T次测样测例
{
cin>>n>>m;//n个人,m对关系
for(int i=1;i<=n;++i)//初始化
{
pre[i]=i;//相当于每个人都互相不认识
}
int a,b;//表示a,b关系
for(int i=0;i<m;++i)//对于每一对关系
{
cin>>a>>b;//读入a,b
mix(a,b);//合并a,b到一棵树内,代表a,b互相认识
}
int ans=0;//结果需要多少张桌子
for(int i=1;i<=n;++i)//对于每一个人
{
if(pre[i]==i)//如果这个人是根节点
++ans;//增加一张桌子
}
cout<<ans<<endl;
}
return 0;
}

代码理解

如果你的朋友非常多(假如有一万个),那么计算需要多少张桌子是不容易的,但是在这时,使用并查集可以更加快速的完成这个计算。首先看代码的函数mix部分,mix函数将判断你输入的一组数据中是否有重复的人出现,若一组数据没有重复键入相同的数据,则将数据进行运行下一个函数,finds函数。find函数是对输入的数据进行关联的函数。在程序的起始部分,定义了1004个数据空间的数组,而finds函数是将输入的两个数据一个作为数组的数组名一个作为数组的元素,接着进行递归,即将数组名下的元素再次作为数组名进行查找,若到最后的元素作为数组名再次查找时查找不到下一个元素即if(pre[x]==x),则进行桌位输出即桌位数加一。

#C++初学记录(并查集)的更多相关文章

  1. 并查集(Java实现)

    (最好在电脑下浏览本篇博客...手机上看代码不方便) 当时学的时候看的一本印度的数据结构书(好像是..有点忘了..反正跟同学们看的都不一样...)...里面把本文提到的所有情况都提到了,我这里只是重复 ...

  2. BZOJ3673/3674:可持久化并查集

    Description n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0& ...

  3. [NOI2018]归程(可持久化并查集,Kruskal重构树)

    解法一: 1.首先想到离线做法:将边和询问从大到小排序,并查集维护连通块以及每个连通块中所有点到1号点的最短距离.$O(n\log n)$ 配合暴力等可以拿到75分. 2.很容易想到在线做法,使用可持 ...

  4. codeforces 1023 D. Array Restoration 并查集

    D. Array Restoration time limit per test 1 second memory limit per test 256 megabytes input standard ...

  5. bzoj 4883 [Lydsy1705月赛]棋盘上的守卫——并查集(思路!)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4883 把各行和各列看成n+m个点. 如果一下能防守行和列,就是最大匹配了.这是每两个左右部点 ...

  6. [APIO2019] [LOJ 3145] 桥梁(分块+并查集)(有详细注释)

    [APIO2019] [LOJ 3145] 桥梁(分块+并查集)(有详细注释) 题面 略 分析 考试的时候就感觉子任务4是突破口,结果却写了个Kruskal重构树,然后一直想怎么在线用数据结构维护 实 ...

  7. hdu 3234 Exclusive-OR (并查集)

    Problem - 3234 题意不难理解,就是给出一些断言,以及一些查询,回答查询或者在找到断言矛盾以后沉默不做任何事. 这题其实就是一个并查集的距离存储问题,只要记录并查集元素的相对值以及绝对值就 ...

  8. PAT Advanced 1034 Head of a Gang (30) [图的遍历,BFS,DFS,并查集]

    题目 One way that the police finds the head of a gang is to check people's phone calls. If there is a ...

  9. #C++初学记录(奶酪#并查集)

    原题目:牛客网 题目描述 : 现有一块大奶酪,它的高度为 h,它的长度和宽度我们可以认为是无限大的,奶酪中间有许多半径相同的球形空洞.我们可以在这块奶酪中建立空间坐标系, 在坐标系中,奶酪的下表面为 ...

随机推荐

  1. PHP-006

    Q:应用程序执行时的路径 "D:\*******\protected\runtime" 是无效的. 请确定它是一个可被 Web server process 写入资料的目录. A: ...

  2. Python 数据类型:列表

    一.列表介绍 1. 列表可以存储一系列的值,使用中括号来定义,每个元素之间用逗号隔开,形如 ['a', 'b', 'c', 'd']2. 列表与元组的区别是:列表中的元素是可变的,元组中的元素是不可变 ...

  3. int()

    int() 用于将一个对象转换为整数,可转换的对象如下: In [1]: int(') # 将纯数字的字符串转换为整数 Out[1]: 10 In [2]: int(10.6) # 将浮点数转换为整数 ...

  4. Android 5.0 API新增和改进

    开始开发 要构建 Android 5.0 版应用,您必须先下载 Android SDK,然后使用 SDK 管理器下载 Android 5.0 SDK 平台和系统映像. 更新您的目标 API 级别 要进 ...

  5. Android SDK更新下载失败以及Studio首次安装取消自动下载SDK

    这是因为,此时Android Studio会去获取 android sdk 组件信息,这个过程相当慢,还经常加载失败,导致Android Studio启动不起开. 解决办法: 不去获取android ...

  6. C语言的基本构成

    C语言的基本构成 知识点:C语言的注释:关键字:书写风格:常量和变量 重要程度:★★★★ 1.C语言的良好风格 用C语言编写的程序,称为C语言源程序,简称C程序. 本节将通过一个简单的C程序例子,向大 ...

  7. C++11新特性之九——function、bind以及lamda表达式总结

    本文是C++0x系列的第四篇,主要是内容是C++0x中新增的lambda表达式, function对象和bind机制.之所以把这三块放在一起讲,是因为这三块之间有着非常密切的关系,通过对比学习,加深对 ...

  8. cocos2d-x游戏引擎核心之十二——3.x新特性

    v3.0 亮点 使用 C++(C++11) 的特性取代了 Objective-C 的特性 优化了 Labels 优化了渲染器(比 v2.2 更快) 新的事件分发机制 物理引擎集成 新的 UI 对象 J ...

  9. EL表达式格式化日期时间

    1.首先引入标签库 <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> ...

  10. MUI Hbuilder设置模拟器运行APP项目

    1 安装hbuilder和夜神模拟器 2 hbuilder  新建app项目 3 hbuilder:运行-> 设置web服务器->Hbuilder 第三方安卓模拟器端口:62001 4 运 ...