并查集(偏移量+路径压缩) 您所在的位置:网站首页 并查集压缩路径 并查集(偏移量+路径压缩)

并查集(偏移量+路径压缩)

2024-03-26 07:58| 来源: 网络整理| 查看: 265

并查集的概念:

并查集是由一个数组、两个函数(查找一个数的根、合并路线)组成,常用来解决一些不相交集合的合并与查找问题。

并查集中有2个重要的函数:一个用来寻找祖先,一个用来合并

祖先:节点指向自身

int find(int x) //寻找x的祖先,这里为了节约时间使用了路径压缩 { return x == p[x] ? x : p[x] = find(p[x]); } 路径压缩:

下图root为祖先,下面依次是他的儿子节点,不难发现下面三个节点的祖先都是root(图里的应该是r1,r2,r3,打错了,懒得改了= =领会精神哈),那么我们可以让这个三个节点都直接指向他们的祖先root 在这里插入图片描述下面是压缩后的路径,这样就可以大大减少查找祖先的时间 在这里插入图片描述 下面是一道并查集的模板题:

亲戚(relation) Description

或许你并不知道,你的某个朋友是你的亲戚。他可能是你的曾祖父的外公的女婿的外甥女的表姐的孙子。如果能得到完整的家谱,判断两个人是否亲戚应该是可行的,但如果两个人的最近公共祖先与他们相隔好几代,使得家谱十分庞大,那么检验亲戚关系实非人力所能及。在这种情况下,最好的帮手就是计算机。为了将问题简化,你将得到一些亲戚关系的信息,如Marry和Tom是亲戚,Tom和Ben是亲戚,等等。从这些信息中,你可以推出Marry和Ben是亲戚。请写一个程序,对于我们的关于亲戚关系的提问,以最快的速度给出答案。

Input

输入由两部分组成。

第一部分以N,M开始。N为问题涉及的人的个数(1≤N≤20000)。这些人的编号为1,2,3,…, N。下面有M行(1≤M≤1 000 000),每行有两个数ai, bi,表示已知ai和bi是亲戚。

第二部分以Q开始。以下Q行有Q个询问(1≤Q≤1 000 000),每行为ci, di,表示询问ci和di是否为亲戚。

Output

对于每个询问ci, di,输出一行:若ci和di为亲戚,则输出“Yes”,否则输出“No”。

Sample Input 1

10 7 2 4 5 7 1 3 8 9 1 2 5 6 2 3 3 3 4 7 10 8 9

Sample Output 1

Yes No Yes

#include using namespace std; const int maxn = 2e5+5; int p[maxn]; int m,n; int find(int x) //这是迭代版本的find函数,使用迭代不容易发生错误 { int k, j, r; r = x; while(r != p[r]) r = p[r]; k = x; while(k != r) { j = p[k]; p[k] = r; k = j; } return r; } int main() { scanf("%d %d",&n,&m); for(int i = 1 ; i x >> y; if(x > n || y > n) { ans++; continue; } int r1 = find(x),r2 = find(y); if(r1 != r2) { p[r1] = r2; dis[r1] = (dis[y] - dis[x] + d - 1 + mod) % mod; } else { if((dis[x] - dis[y] + mod) % mod != d - 1) ans++; } } cout y >> c; if(c == 'D') { k1 = find(p[x][y]); k2 = find(p[x+1][y]); } else { k1 = find(p[x][y]); k2 = find(p[x][y+1]); } if(k1.x == k2.x && k1.y == k2.y) { cout


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有