并查集在连通图上的应用
连通图定义:在无向图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;
}
}