如何判断图的连通

判断图是否连通,可用dfs和bfs遍历图算法,注意点数目较多,又是稀疏图的话,最后使用邻接表的方法存储。另外推荐采用的是并查集的方法。初始化时将每个节点看作一个集合,则每给出一条边即把两个集合合并。最后遍历所有点,有几个集合便有几个连通分量,若只有一个集合说明图连通。并查集方法通常情况下时间效率较高,还能判断一个图是否有回路,在kruskal算法中也可以使用。

(1)DFS判断

int count = 0;
void DFS(MGrap G. int i)
{
    int j = 0;
    visited[i] = 1;
    count++;
    for(j=0; j<G.numVertexes; j++)
    {
        if(G.arc[i][j]==1 && !visited[j])//i和j有关系相邻,并且j顶点没有被访问过
        {
            DFS(G, j);
        }
    }
}

从某一点出发开始DFS,到最后,只需要判断最后count的值是否是全部的节点就可以,如果小于总节点数,则证明是不连通的,如果相等,则证明是连通的。

还可以访问完一个节点,就将其删除掉,可提高遍历速度

void dfs(int s){             //递归深搜
    vis[s]=true;
    for(int i=0;i<g[s].size();++i){
        if(vis[g[s][i]]) g[s].erase(g[s].begin()+i);//删除图中已经遍历过的点,可提高遍历速度
        else dfs(g[s][i]);
    }
}

bool judge(){                //判断是否所有点已被遍历过
    for(int i=1;i<=n;++i)
        if(!vis[i])
            return false;
    return true;
}

(2)BFS判断

void bfs(int s){            //用队列广搜
    queue<int> q;
    q.push(s);
    while(!q.empty()){
        int x=q.front();
        q.pop();
        vis[x]=true;
        for(int i=0;i<g[x].size();++i){
            if(vis[g[x][i]]) g[x].erase(g[x].begin()+i);//删除图中已经遍历过的点,可提高遍历速度
            else q.push(g[x][i]);
        }
    }
}

bool judge(){                   //判断是否所有点已被遍历过
    for(int i=1;i<=n;++i)
        if(!vis[i])
            return false;
    return true;
}

同样如果从某一个节点广度搜完,有未访问到的节点,那么该图一定是不连通的。

(3)并查集

并查集一般用来判断图的连通性,还可以判断图中是否有回路。

如果并查集最后只有一个连通分量,证明此图连通,否则此图不连通

int set[1000005];

int find(int x){

   return x==set[x]?x:(set[x]=find(set[x]));   //递归查找集合的代表元素,含路径压缩。

}
int main()

{

   int n,m,i,x,y;

   scanf("%d%d",&n,&m);

   for(i=1;i<1000005;++i)        //初始化个集合,数组值等于小标的点为根节点。

       set[i]=i;

   for(i=0;i<m;++i){

       int a,b;

       scanf("%d%d",&a,&b);

       int fx=find(a),fy=find(b);

       set[fx]=fy;                      //合并有边相连的各个连通分量

   }

   int cnt=0;

   for(i=1;i<=n;++i)          //统计集合个数,即为连通分量个数,为一时,图联通。

       if(set[i]==i)

           ++cnt;

   if(cnt==1)

       printf("yes\n");

   else printf("no\n");

   return 0;

}

原文地址:https://www.cnblogs.com/mini-coconut/p/9484596.html

时间: 2024-10-15 12:19:40

如何判断图的连通的相关文章

并查集-判断图的连通

来看一个实例,杭电1232畅通工程 首先在地图上给你若干个城镇,这些城镇都可以看作点,然后告诉你哪些对城镇之间是有道路直接相连的.最后要解决的是整幅图的连通性问题.比如随意给你两个点,让你判断它们是否连通,或者问你整幅图一共有几个连通分支,也就是被分成了几个互相独立的块.像畅通工程这题,问还需要修几条路,实质就是求有几个连通分支.如果是1个连通分支,说明整幅图上的点都连起来了,不用再修路了:如果是2个连通分支,则只要再修1条路,从两个分支中各选一个点,把它们连起来,那么所有的点都是连起来的了:如

EOJ 1816 并查集的的简单应用——判断图联通

题目:eoj1816 题目分析:判断图是否连通,可用dfs遍历图算法.这里我采用的是并查集的方法.初始化时将每个节点看作一个集合,则每给出一条边即把两个集合合并.最后遍历所有点,有几个集合便有几个连通分量,若只有一个集合说明图连通. AC代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <string> #include &

?数据结构-图之强连通

数据结构-图之强连通 在一个无向图G中,若从顶点v_i到顶点v_j有路径相连(当然从v_j到v_i也一定有路径),则称v_i和v_j是连通的.如果G是有向图,那么连接v_i和v_j的路径中所有的边都必须同向.如果图中任意两点都是连通的,那么图被称作连通图.图的连通性是图的基本性质. 连通分量:无向图G的一个极大连通子图称为G的一个连通分量(或连通分支).连通图只有一个连通分量,即其自身:非连通的无向图有多个连通分量. 初级通路:通路中所有的顶点互不相同.初级通路必为简单通路,但反之不真. 强连通

HDU-1232 畅通工程 (并查集、判断图中树的棵数)

Description 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇.省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相间接通过道路可达即可).问最少还需要建设多少条道路? Input 测试输入包含若干测试用例.每个测试用例的第1行给出两个正整数,分别是城镇数目N ( < 1000 )和道路数目M:随后的M行对应M条道路,每行给出一对正整数,分别是该条道路直接连通的两个城镇的编号.为简单起见,城镇从1到N编号. 注意

图之强连通、强连通图、强连通分量 Tarjan算法

强连通分量 简介 在阅读下列内容之前,请务必了解图论基础部分. 强连通的定义是:有向图 G 强连通是指,G 中任意两个结点连通. 强连通分量(Strongly Connected Components,SCC)的定义是:极大的强连通子图. 这里想要介绍的是如何来求强连通分量. Tarjan 算法 Robert E. Tarjan (1948~) 美国人. Tarjan 发明了很多算法结构.光 Tarjan 算法就有很多,比如求各种联通分量的 Tarjan 算法,求 LCA(Lowest Comm

Geeks - Detect Cycle in a Directed Graph 判断图是否有环

Detect Cycle in a Directed Graph 判断一个图是否有环,有环图如下: 这里唯一注意的就是,这是个有向图, 边组成一个环,不一定成环,因为方向可以不一致. 这里就是增加一个数组保存当前已经访问过的路径信息 recStack[]: 而visited[]数组是访问过的点的信息,两者作用是不一样的. 知道这个知识点,这道题就很容易了. 原文: http://www.geeksforgeeks.org/detect-cycle-in-a-graph/ #include <st

poj 3352 Road Construction【边双连通求最少加多少条边使图双连通&amp;&amp;缩点】

Road Construction Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10141   Accepted: 5031 Description It's almost summer time, and that means that it's almost summer construction time! This year, the good people who are in charge of the r

判断图中是否有环的方法

一.无向图 方法一:n算法: 原理是: 如果存在回路,则必存在一个子图,是一个环路.环路中所有顶点的度>=2. 第一步:删除所有度<=1的顶点及相关的边,并将另外与这些边相关的其它顶点的度减一. 第二步:将度数变为1的顶点排入队列,并从该队列中取出一个顶点重复步骤一. 如果最后还有未删除顶点,则存在环,否则没有环. 方法2: DFS搜索图,图中的边只可能是树边或反向边,一旦发现反向边,则表明存在环.该算法的复杂度为O(V). 二.有向图 主要有深度优先和拓扑排序两种方法 判断图中是否有环的方法

求图的连通块

求连通块 Time Limit: 1sec    Memory Limit:256MB Description 输入一个简单无向图,求出图中连通块的数目. Input 输入的第一行包含两个整数n和m,n是图的顶点数,m是边数.1<=n<=100,0<=m<=10000. 以下m行,每行是一个数对u v,表示存在边(u,v).顶点编号从1开始. Output 单独一行输出连通块的数目. Sample Input 5 3 1 2 1 3 2 4 Sample Output 2 这个题目