问题描述:
如何用程序判断一个图是否连通???
连通?何为连通?
就是在一个图中,任取两个顶点,我们都能找到一条路径从一点到达另一个点,这个图就是连通的。
如图就是连通的
选取 0 和 1,有一条路径;选取0 和 3 ,有一条路径 0->2->3…..
那么这个图就是不连通的:
怎样判断?
很自然的想法就是用DFS(深度优先遍历)的方法。那么还有一个方法,其实是非常好用的,它就是并查集。
我们这一篇就先讲一下DFS法。
- DFS:
把一个图的所有顶点都进行一次DFS,当然,进行DFS的前提必须是这个点没有被遍历过。所以如果一个图是连通的,那么从一个点开始DFS,所有的点都会被遍历到,这样其他4个顶点就不用再DFS了。按照这个思路,定义一个count为DFS过顶点的个数,如果count=1,则图为连通的,否则就是大于1,,这样就是不连通的。
我们可以用DFS模拟一下判断连通性这个过程,还是用这个图吧!
我们将顶点0到顶点4进行一次DFS,假设每个顶点都有一个性质known,如果known为false,则可以DFS。伪代码如下:
count = 0
for v 0 to 4
if known[v] is false
DFS(v)
count++
在DFS的过程中,将遍历到的点的known设为true。用数组P来表示图的邻接矩阵。
DFS的伪代码如下
DFS (v)
for u 0 to 4
if p[v][u] is 1 && known[u] is flase
known[u] is true
DFS (u)
这样判断一下count是否为1即可。
完整代码如下:
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 100;
int p[maxn][maxn];
int known[maxn];
int v,e;
void DFS(int s)
{
for(int u=0; u<v; u++)
{
if(!known[u]&&p[s][u])
{
known[u] = 1;
DFS(u);
}
}
return;
}
int main()
{
while(scanf("%d%d",&v,&e)!=EOF)
{
memset(p,0,sizeof(p));
memset(known,0,sizeof(known));
int s,t;
for(int i=0; i<e; i++)
{
scanf("%d%d",&s,&t);
p[s][t] = 1;
p[t][s] = 1;
}
int count = 0;
for(int i=0; i<v; i++)
{
if(!known[i])
{
DFS(i);
count++;
}
}
if(count == 1)
{
printf("是连通图\n");
}else{
printf("不是连通图,count=%d\n",count);
}
}
return 0;
}
效果图如下: