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