并查集|无向图的连通分量

并查集

应用:连通子图,最小生成树,kruskal算法,最近公共祖先(LCA)

基本操作

1.初始化init,所有元素自己是自己的父节点

2.查询find  递归查询 最终的祖先

3.合并unionn  合并最终的父节点

题目:

给出一个无向图G,求其连通分量的数量。

输入格式:

第1行输入正整数N(0<N≤1000)和E(0<E≤5000),为顶点个数和边数。 N个结点的序号依次为1~N,接下来E行每行输入连接边的两个顶点编号。

输出格式:

输出以上图的连通分量的数目。

输入样例1:

7 5
5 6
1 2
1 4
2 3
3 4

输出样例1:

3

//寻找每个数字的父节点给有没有改变如果改变了则说明连通了
//没改变(保持和自己相连接)就是不连通
 

//寻找每个数字的父节点给有没有改变如果改变了则说明连通了
//没改变(保持和自己相连接)就是不连通 

#include<iostream>
#define MAXN 1000
using namespace std; 
int fa[MAXN];


void init(int n){
	for(int i = 0; i <= n;i++)
		fa[i] = i;//存储每个元素的父节点
	 //将自己设为父节点 
}
int find(int i ){
	if(fa[i] == i) 
		return i;//自己是自己的父节点 
	else 
	{
		fa[i] = find(fa[i]); //使用路径压缩 
		return fa[i];//返回父节点 
	}
} 
void unionn(int i, int j){
	int i_fa = find(i);//找i的父节点 
	int j_fa = find(j);//找j的父节点 
	fa[i_fa] = j_fa;//i 的祖先指向j的祖先 	
} 

int main(){
	int n,m;
	int x,y;
	cin>>n>>m;
	init(n);
	for(int i = 0;i<m;i++){
		cin>>x>>y;
		//fa[find(x)] = find(y);
		unionn(x,y);//两个节点连接到一个父节点上,说明有数和它相连 
	}
	int res = 0;
	for(int i = 1;i <= n;i++){
		if(fa[i] == i) res ++;
	}
	cout<<res<<endl;
} 

猜你喜欢

转载自blog.csdn.net/Brittney27/article/details/134812616
今日推荐