图的连通性问题-并查集

图论中有一个基本的问题,那就是一个无向图的连通性判别问题,今天我们就来讨论这个问题,我们知道,在计算机中一张图可以有两种表示方法,一是邻接矩阵二是邻接表,其中的邻接矩阵表示方法,我们已经在课堂上介绍最小生成树问题时讨论过,今天我们就来讨论用邻接表表示的图的连通性问题。要求用并查集方法求解。

Input

本问题有多组测试数据,每组测试数据有两部分,第一部分只有一行,是两个正整数,分别表示图的节点数N(节点
编号从1到N,1<=N<=100)和图的边数E;第二部分共有E行,每行也是两个整数N1,N2(1<=N1,N2<=N),分
别表示N1和N2之间有一条边。

Output

对于每一组测试数据,输出只有一行,如果是连通图,那么输出“Yes”,否则输出“No”。

Sample Input

6 10
1 2
1 3
1 4
1 5
1 6
2 3
2 4
3 4
3 5
3 6
4 3
1 2
1 3
2 3

Sample Output

Yes
No
#include<bits/stdc++.h>
using namespace std;
const int MAXN=100005;
int fa[MAXN],tot,n,m,u,v;
int findf(int x)
{
    return x==fa[x]?x:fa[x]=findf(fa[x]);
}
void unions(int x,int y)
{
    if(findf(x)!=findf(y))
    fa[findf(x)]=findf(y);
}
int main()
{
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        for(int i=1;i<=n;++i)
        {
            fa[i]=i;
        }
        for(int i=1;i<=m;++i)
        {
            scanf("%d %d",&u,&v);
            unions(u,v);
        }
        bool f=true;
        for(int i=1;i<=n;++i)
        {
            if(findf(i)!=findf(1))f=false;
        }
        printf("%s\n",f?"Yes":"No");
    }
    return 0;
}
#include<bits/stdc++.h>
using namespace std;
int n,m;vector<int>vec[1000];
int pre[1000];int vis[1000];
int count1;
int find(int x)
{
	int r=x;
	while(pre[r]!=r)
	r=pre[r];
	return r;
}
void mix(int x,int y)
{
	int fx=find(x);int fy=find(y);
	if(fx!=fy)
	{
		if(fx<fy)
		pre[fx]=fy;
		else
		pre[fy]=fx;
	}	
}
int main()
{
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		for(int i=1;i<=n;i++)
		pre[i]=i;
		while(m--)
		{
			int x,y;
			cin>>x>>y;
			mix(x,y);
		}
		memset(vis,0,sizeof(vis));
	    for(int i=1;i<=n;i++)
	    {
	    	vis[i]=find(i);
		}
	   bool flag=true;
	   for(int i=1;i<=n;i++)
	   {
	   	if(vis[i]!=vis[1])
	   	flag=false;
	   }	   
	     if(flag)
	     cout<<"Yes"<<endl;
	     else
	     cout<<"No"<<endl;
	}	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44061561/article/details/94449271