介绍并查集比较清楚的文章
https://blog.csdn.net/zjy_code/article/details/80634149
上面的那篇文章写得不错,有一个例子可以让你深入理解并查集
一个数据结构理论上可以解决的同系列问题是无穷的,就好比,有了砖头,可以盖的建筑物是无穷的
找朋友
在社交的过程中,通过朋友,也能认识新的朋友。在某个朋友关系图中,假定 A 和 B 是朋友,B 和 C 是朋友,那么 A 和 C 也会成为朋友。即,我们规定朋友的朋友也是朋友。
现在,已知若干对朋友关系,询问某两个人是不是朋友。
请编写一个程序来解决这个问题吧。
输入格式
第一行:三个整数 n,m,p(n≤5000,m≤5000,p≤5000)分别表示有n 个人,m 个朋友关系,询问p 对朋友关系。
接下来 m 行:每行两个数Ai,Bi1≤Ai,Bi≤N,表示Ai 和 Bi具有朋友关系。
接下来 p 行:每行两个数,询问两人是否为朋友。
输出格式
输出共 p 行,每行一个Yes或No。表示第i个询问的答案为是否朋友。
样例输入
6 5 3
1 2
1 5
3 4
5 2
1 3
1 4
2 3
5 6
样例输出
Yes
Yes
No
题解::
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
int mark[5005],fa[5005];
int get(int x)
{
if(fa[x]==x)
return x;
return fa[x]=get(fa[x]);
}
int main()
{
int n,m,p;
cin>>n>>m>>p;
int a,b;
memset(mark,0,sizeof(mark));
for(int i=1;i<=n;i++)
fa[i]=i;
while(m--)
{
cin>>a>>b;
a=get(a);
b=get(b);
if(a!=b)
{
fa[a]=b;
}
}
for(int i=1;i<=p;i++)
{
cin>>a>>b;
a=get(a);
b=get(b);
if(a==b)
mark[i]=1;
}
for(int i=1;i<=p;i++)
{
if(mark[i])
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
}
return 0;
}
结论:
现在有一个N个元素的集合,如果现在查询的次数 + 合并的次数 >= N 我们就可以说单次查询和单次合并的平均时间复杂度是o(1)。这个结论在算法导论中花了40页去证明
左神说,有一个函数就算参数是10的80次方(目前人类所探明的宇宙的总原子数),返回值不会大于6,也就是说上面的结论还是o(6),也就是o(1),有一个人证明了25年。