无向图的连通性问题(DFS)

来源:互联网 发布:钱永健 知乎 编辑:程序博客网 时间:2024/05/16 11:10

问题描述:
如何用程序判断一个图是否连通???

连通?何为连通?

就是在一个图中,任取两个顶点,我们都能找到一条路径从一点到达另一个点,这个图就是连通的。

如图就是连通的
这里写图片描述
选取 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 = 0for 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;}

效果图如下:
这里写图片描述

0 0
原创粉丝点击