并查集

并查集

日常膜拜dalao:财神万岁!!!!!!!!!!!!!!!!!!!!
emm因为刚刚写了一篇题解想起来要写并查集的了,然而明天分班考试我丝毫不慌稳如泰山甚至还贼想写博客。。。

啥是并查集?

不相交数据结构。维护一个森林,使得每棵树之间不相交,并能够统计出有多少个独立的树 。染色方法,不断地合并,顺便路径压缩,把同一个树的高度尽量降低来进行时间优化 。

看不懂是不是?没关系我们通俗一点。
假设我们已知一堆关系,A和B是亲戚,B和C是亲戚,那么A和C也是亲戚。
给你这些关系,让你梳理好他们之间谁谁之间都是亲戚。

并查集的要点:

找祖先函数:找到x 的最早的祖先,然后把跟x 有关系的都连接到x 的祖先上,这样查询会方便很多也快捷很多,不然一层层找下来很烦的qwq
初始化:很重要!每个人最初开始的祖先都是他本身。
emm剩下的代码里面很清楚,看代码吧

include<iostream>//并查集 
#define maxn 105
#define maxm 105
using namespace std;
int   m,n;// n个点,m 条边 
int f[maxn]; //祖先 
int h[maxn]; //树高 
void chushihua()//初始化,一定要有!
{
	for(int i=1;i<=n;i++){
		h[i]=1;//树高 
		f[i]=i;//祖先最开始是它本身 
	}//初始化每一个点
	return;
}
int get(int x)//找祖先的函数 
{
	if(f[x]==x) return x;//如果祖先是他自己时返回自己 
	else{
		f[x]=get(f[x]);//找到他的最终祖先 
		return f[x];//顺便路径压缩,一层一层返回上去它的祖先 
	}
}
void merge(int a,int b)//将a和b合并到一棵树上面 
{
	int t1=get(a),t2=get(b);//分别找a,b的最终祖先 
	if(t1==t2) return;//已经在同一棵树中 
	if(h[t1]<h[t2]) swap(t1,t2);//靠左原则,左边比右边的树要高 
	if(t1!=t2){
		f[t2]=t1;//左边的变成右边的祖先
		h[t1]=max(h[t1],h[t2]+1);//合并树高,原树高与合并来的比较并进行更新 
	}
	return;
 } 
 int main()
 {
 	cin>>n>>m;
 	chushihua();
 	for(int i=1;i<=m;i++)
 	{
 		int a;int b;
 		cin>>a>>b;
 		merge(a,b);//合并a,b所在的树 
	 }
	。。。。。。//其他操作
 	return 0;
} 

我们用f[i]表示i的祖先,当每次需要查找i和j之间的关系时,只需要查找 f[i]和f[j]之间的关系,h数组是树高,当合并两棵树时,我们优先把低的树合并到高的树上面,对时间复杂度进一步优化。

emm其实我讲的一点也不仔细,,如果实在看不明白这里有一片详细的多的大佬的博客
友情链接:https://blog.csdn.net/Martisum/article/details/99721621

本文如有不周到处欢迎评论,
感谢各位神犇对本蒟蒻的支持!qwq

你可能感兴趣的:(图论算法)