王道_例11.2判断连通图(并查集)

并查集在连通图上的应用

连通图定义:在无向图G中,若顶点u到顶点v有路径相连,称u和v是连通的。若图中任意两点是连通的,图被成为连通图

连通分量:无向图G中的一个极大连通子图称为G的一个连通分量,连通图只有一个连通分量,即自身。

思路

不断合并图中边相连的两个点所属的集合,最后计算出集合的个数就是连通分量的个数。连通分量为一则为连通图。

代码

//判断无向图是否为连通图
#include <iostream>
using namespace std;
const int MAXN=1000;
int father[MAXN];//记录父节点 
int height[MAXN];//记录高度 
void Initial(int n)
{
    
    
	for(int i=0;i<n;++i)
	{
    
     
		father[i]=i;//初始时节点的父亲为节点本身 
		height[i]=0; 
	} 
}
//查找父节点,最终返回父节点 
int Find(int x)
{
    
    
	if(x!=father[x])
	{
    
    
		father[x]=Find(father[x]);
	}
	return father[x];
 }
 //合并节点 
 void Union(int x,int y)
 {
    
    
 	x=Find(x);
	y=Find(y);
	//两个节点不在同一个集合中时 
	if(x!=y)
	{
    
    
		if(height[x]>height[y])
			father[y]=x;
		else if(height[x]<height[y])
			father[x]=y;
		else
		{
    
    	father[x]=y;
			height[x]++;} 
	 } 
  } 
int main()
{
    
    
	int n,m;//顶点数 边数
	while(cin>>n)
	{
    
    
		cin>>m;
		if(n==0) break;
		Initial(n);//初始化,初始所有的顶点是孤立的
		while(m--)
		{
    
    
			int x,y;
			cin>>x>>y;//输入边
			Union(x,y);//集合合并 
		 } 
		int number=0;
		for(int i=0;i<n;++i)
		{
    
    
			if(Find(i)==i) ++number; 
		 } 
		if(number==1) cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
	 } 
 } 

猜你喜欢

转载自blog.csdn.net/weixin_45019830/article/details/115010866