说句实话,我和并查集的缘分还是蛮深的,因为当年学完数论想着找板子题乱做(真是个神奇的找题方式呢),然后就看到了并查集QWQ,看了一会发现是图论就不看了,,,,,,结果还被说是大佬QWQ其实我只是个NaCl Fish而已QAQ

好了现在终于学了并查集,那我们就来总结总结

这一次总共是有三道题要讲

首先我们来看看板子题

P3367 【模板】并查集

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

所谓并查集,其实就是并       查         集        这一点看题面就能理解了

这里看一下   并(把两个集合合并到一起)

void merge(int a, int b)
{
father[search(a)]=search(b);
}

这里看一下    查(查一个点的祖宗是啥)

int search(int a)
{
if (father[a] == a)
return a;
return father[a] = search(father[a]);
}

这里形象的理解一下(某谷题解)

关于并查集和路径压缩:

有a,b,c三个人

假设a和b打架了,a做了b的小弟。则令f[a]=b;

后来a打赢了c

那么c就是a的小弟了。所以,令f[c]=a;

但是,c不知道b,这不符合要求。

所以,我们必须让c的大哥变成最大的老大。

这个就是查的过程

int search(int a)
{
if (father[a] == a)
return a;
return father[a] = search(father[a]);
}

这里我用了一个比较好的优化技巧,就是在找一个点的祖宗的时候,一块把所有经过的点的祖宗都进行标记,这样就比较快了,看一下代码的话,也是赋了一个递归函数的返回值。这样的话找爹就更容易点了

代码贴一下

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int n, m, x, y, z, father[], t1, t2;
int search(int a)
{
if (father[a] == a)
return a;
return father[a] = search(father[a]);
}
void merge(int a, int b)
{
father[search(a)]=search(b);
}
int main()
{
scanf("%d%d", &n, &m);
for (int i = ; i <= n; ++i)
father[i] = i; for (int i = ; i <= m; ++i)
{
scanf("%d%d%d", &z, &x, &y);
if (z == )
merge(x, y);
else
{
if (search(x) == search(y))
printf("Y\n");
else
printf("N\n");
}
}
return ;
}

那么我们看下一个题

P1551 亲戚

这个题吧其实也算得上是一道并查集的板子题了,主要的就是分析一下要你干什么

我们来看看

,首先,我们假设每一个人都是一个独立的集合,在他输入两个人之间是亲戚关系的时候,我们就需要把这两个人所在的集合合并了,还是用到了上面的代码

这里边读入边合并,最后直接输出找爹结果就行了(还是挺水的)

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int n, m, x, y, z, father[], p;
int search(int a)
{
if (father[a] == a)
return a;
return father[a] = search(father[a]);
}
void merge(int a, int b)
{
father[search(a)] = search(b);
}
int main()
{
scanf("%d%d%d", &n, &m, &p);
for (int i = ; i <= n; ++i)
father[i] = i;
for (int i = ; i <= m; ++i)
{
scanf("%d%d", &x, &y);
merge(x, y);
}
for (int i = ; i <= p; ++i)
{
scanf("%d%d", &x, &y);
if (search(x) == search(y))
printf("Yes\n");
else
printf("No\n");
}
return ;
}

最后一个题是这货

P3984 高兴的津津

这个题的标签是这样的

所以蒟蒻我一开始只是用数学方法做的啊QWQ

讲讲数学加模拟的实现吧

首先我们知道津津AKIOI之后会开心t天,但是在这t天以内,如果她再次AK,那么时间从头算起,这样的话,我们就可以比较每两个数的差,看是否大于t并且进行运算啦

贴代码,跑路~

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int n, t, a[], ans;
int main()
{
scanf("%d%d", &n, &t);
for (int i = ; i <= n; ++i)
{
scanf("%d", &a[i]);
if (i != )
{
if (a[i] - a[i - ] > t)
ans += t;
else
ans += a[i] - a[i - ];
}
}
ans += t;
printf("%d", ans);
return ;
}

并查集(我根本不会切板子啊喂QWQ长文)(大雾的更多相关文章

  1. CF # 296 C Glass Carving (并查集 或者 multiset)

    C. Glass Carving time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  2. TZOJ 3042 切蛋糕(并查集)

    描述 KK是个心灵手巧的好姑娘,她做了一个大蛋糕请她的好朋友们来品尝.这个蛋糕分成n×n个正方形小格,每个小格包含一块水果.KK要把蛋糕切成若干块,显然她不会破坏任意一个小格.无聊的某同学在她切蛋糕时 ...

  3. [poj-2985]The k-th Largest Group_Treap+并查集

    The k-th Largest Group poj-2985 题目大意:给你n只猫,有两种操作:1.将两只猫所在的小组合并.2.查询小组数第k大的小组的猫数. 注释:1<=n,m<=20 ...

  4. hdu 5458 Stability(树链剖分+并查集)

    Stability Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 65535/102400 K (Java/Others)Total ...

  5. 洛谷P3295 萌萌哒 并查集 + ST表

    又切一道紫题!!! 成功的(看了一吨题解之后),我A掉了第二道紫题. 好,我们仔细观察,发现这是一个排列组合问题. 有些限定条件,要相等的地方,我们就用并查集并起来.最后一查有多少个并查集,就有多少个 ...

  6. bzoj 3673&3674 可持久化并查集&加强版(可持久化线段树+启发式合并)

    CCZ在2015年8月25日也就是初三暑假要结束的时候就已经能切这种题了%%% 学习了另一种启发式合并的方法,按秩合并,也就是按树的深度合并,实际上是和按树的大小一个道理,但是感觉(至少在这题上)更好 ...

  7. 【BZOJ4382】[POI2015]Podział naszyjnika 堆+并查集+树状数组

    [BZOJ4382][POI2015]Podział naszyjnika Description 长度为n的一串项链,每颗珠子是k种颜色之一. 第i颗与第i-1,i+1颗珠子相邻,第n颗与第1颗也相 ...

  8. C. Glass Carving (CF Round #296 (Div. 2) STL--set的运用 &amp;&amp; 并查集方法)

    C. Glass Carving time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  9. [bzoj3910]火车_并查集_倍增LCA

    火车 bzoj-3910 题目大意:给定一棵n个节点的树,你需要顺次经过m个互不相同的节点,如果一个节点在之前的路径上被经过过,它不必再被特意经过.问走过的路径长度. 注释:$1\le n\le 5\ ...

随机推荐

  1. EF 查询视图出现重复数据

    解决方案: 由多张表组成的视图,要加实体键.而且实体键组合要能确保唯一性. 个人理解:确保唯一性,一个或多个实体键,实现了复合主键或组合主键的效果. 这样查询是,延迟加载机制,才知道哪些需要重新从数据 ...

  2. 《JavaScript高级程序设计》笔记:客户端检测(九)

    能力检测 在编写代码之前先检测特定浏览器的能力.例如,脚本在调用某个函数之前,可能要先检测该函数首付存在.这种检测方法将开发人员从考虑具体的浏览器类型和版本中解放出来,让他们把注意力集中到相应的能力是 ...

  3. shell 查找与替换

    grep sed 如果想把一个字符串中的一些字符删除可以如此:#Echo “2006-11-21 22:16:30” | sed ‘s/-//g’ | sed ‘s/ //g’ | sed ‘s/:/ ...

  4. Android为TV端助力 使用shared注意事项

    不要存放大的key和value!我就不重复三遍了,会引起界面卡.频繁GC.占用内存等等,好自为之! 毫不相关的配置项就不要丢在一起了!文件越大读取越慢,不知不觉就被猪队友给坑了:蓝后,放进defalu ...

  5. 工具资源系列之给虚拟机装个windows

    前面我们介绍了如何在 mac 宿主机安装 VMware 虚拟机软件,本节我们将继续介绍如何给虚拟机安装镜像,切换不同的操作系统. VMware 软件是容器,镜像是内核,这里的镜像指的是操作系统. 下载 ...

  6. 谈下git的基本操作

    在工作之后,我比较经常地接触git,关于git的用法,网上有很多的教程,而且git的指令是非常多的,强如阮一峰这样的高手也直言无法记住git的很多指令.实际上我也看了不少关于git指令的文章,个人觉得 ...

  7. Python 经典面试题汇总之网络篇

    网络篇 1.简述 OSI 七层协议 物理层:定义物理设备标准,如网线的接口类型.光纤的接口类型.各种传输介质. 数据链路层:定义如何传输格式化数据,以及如何访问物理介质. 网络层:定义逻辑网络地址. ...

  8. 「Python」为什么Python里面,整除的结果会是小数?

    2018-06-08 参考资料:Python学习笔记(4)负数除法和取模运算 先来看三个式子(!这是在Python3.0下的运算结果): 输出结果: ‘//’明明是整除,为什么结果不是整数,而会出现小 ...

  9. LeetCode算法题-Self Dividing Numbers(Java实现)

    这是悦乐书的第305次更新,第324篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第173题(顺位题号是728).自分割数是一个可被其包含的每个数字整除的数字.例如,12 ...

  10. C++一些基本数据结构:字面常量、符号常量、枚举常量

    常量:C++包括两种常量,字面常量和符号常量. 字面常量:指的是直接输入到程序中的值 比如:in myAge=26: myAge是一个int类型变量,而26是一个字面常量. 符号常量:指的是用名称表示 ...