无向图求桥的几种方法(无重边)

目录

前言:

法一:计算连通分量的基准法

描述:

时间复杂度分析:

数据:

法二:找结点基准法

描述:

时间复杂度分析:

数据:

法三:并查集

描述:

按秩合并:

路径压缩:

时间复杂度分析:

数据:

法四:生成树筛边基准法

描述:

时间复杂度分析:

数据:

法五:生成树筛边并查集

描述:

时间复杂度分析:

数据:

法六、Tarjan算法

描述:

实现细节:

举例:

时间复杂度分析:

数据:


前言:

一图中求桥的方法有很多种,以下介绍6种求桥的方法

有一个结论:当图的连通子图的个数 ≥ 2的时候,邻接表一定比矩阵快

举例:假设一个图有10000个结点,其中的一个连通子图只有3个结点2条边,那么在判断这个结点上的2条边是否为桥的时候,邻接表只需要2次即可找到这2条边,而矩阵需要2*10000次才可以找到这2条边

所以后文中图的存储结构都是采用的邻接表,不会混用邻接表和邻接矩阵

法一:计算连通分量的基准法

描述:

假设边e连接着2个顶点v1和v2

对全图做DFS计算出连通子图个数k1

删掉边e

再对全图做DFS计算出连通子图个数k2

若k2

时间复杂度分析:

对全图做DFS需要O(n+e)

有e条边

需要对全图做e次DFS,总时间为O(en+e²)

稀疏图:O(n²)

稠密图:O(n^4)

数据:

无向图求桥的几种方法(无重边)_第1张图片

                                                  图1、计算连通分量基准法数据

可以看出此方法的速度是非常慢的

 

法二:找结点基准法

描述:

假设边e连接着2个顶点v1和v2,删掉边e,对顶点v1进行DFS

如果v2在v1的DFS中,则边e不是桥

如果v2不在v1的DFS中,则边e是桥

时间复杂度分析:

假设图有n个顶点,e条边

需要做e次DFS

每次DFS时间为O(e)

总时间为:O(e²)

 

稀疏图:O(n²)

稠密图:O(n^4)

数据:

无向图求桥的几种方法(无重边)_第2张图片

                                                  图2、找结点基准法的稀疏图数据

由图2可以知道,在稀疏图中,找结点基准法比计算连通分量的基准法快很多

无向图求桥的几种方法(无重边)_第3张图片

                                                  图3、找结点基准法的稠密图数据

由图3可以知道,在稠密图中,找结点基准法比计算连通分量的基准法快很多

因此,找结点基准法是一种比计算连通分量基准法更优秀的算法

 

法三:并查集

描述:

假设边e连接着2个顶点v1和v2

删掉边e

刷新图的各结点的集合

若v1和v2在同一个集合中,则边e不为桥

若v1和v2不在同一个集合中,则边e为桥

按秩合并:

在集合的合并中,将小集合合并到大集合中

 

路径压缩:

在Union操作中,由于大部分新加入的结点都是加在集合树的叶子上,所以会导致集合树的深度过大,那么可以在Find操作中,将叶子结点人工地指向根结点,这样就可以降低树的高度,提高find的效率

 

时间复杂度分析:

假设图有n个顶点,e条边

初始化需要n次MAKE-SET操作

判断每条边需要做2次FIND-SET操作,判断图共2e次FIND-SET操作

每个顶点需要做一次UNION操作,判断图共n次UNION操作

由书上定理21.14,最坏需要O((n+2e+n)α(n))取O ((n+2e+n))

所以更新一次集合的时间为O ((n+2e+n))

由于有e条边,需要更新e次集合,所以总时间为:O ((2ne+2e²))

稀疏图:O(n²)

稠密图:O(n^4)

数据:

无向图求桥的几种方法(无重边)_第4张图片

图4、并查集的稀疏图数据

由图可以得出稀疏图中并查集的增长仍是符合O(n²)的,而且速度比计算连通分量的基准法快,但比找结点基准法慢

法四:生成树筛边基准法

描述:

在做基准法之前,先用DFS扫出生成树,只对生成树上的边做基准法

时间复杂度分析:

无向图求桥的几种方法(无重边)_第5张图片

 

数据:

稀疏图:

无向图求桥的几种方法(无重边)_第6张图片

图5、生成树筛边基准法的稀疏图数据

由图5可以得出:在边数小于顶点数时,由于找到生成树需要额外的时间,所以生成树基准法比找点基准法慢

稠密图:

无向图求桥的几种方法(无重边)_第7张图片

图6、生成树筛边基准法的稠密图数据

由图6可以看出:在边数远大于顶点数时,生成树基准法所需要判断是否为桥的边远小于基准法中要判断的边,所以生成树基准法快于基准法

 

法五:生成树筛边并查集

描述:

在做基准法之前,先用DFS扫出生成树,只对生成树上的边做并查集

 

时间复杂度分析:

无向图求桥的几种方法(无重边)_第8张图片

 

数据:

结点个数为10000,边数为n时数据

无向图求桥的几种方法(无重边)_第9张图片

图7、生成树筛边并查集数据

由图7可以得出:

某些边数小的区间内,生成树并查集慢于并查集

在边数大的区间,生成树并查集快于并查集,因为边数多的时候,生成树并查集所需要判断是否为桥的边远小于并查集中要判断的边,所以生成树并查集快于并查集

 

法六、Tarjan算法

描述:

从某个顶点开始进行DFS,并进行标号

如果某个结点的某条边的DFS中有某个孩子有边指向这个结点或这个结点的祖先,那么这条边为桥

实现细节:

设置一个visit数组表示访问的顺序

设置一个low数组,low[i]表示结点i的孩子中指向的最早的祖先

low[v] = min { visit[v], low[w], visit[k] }

其中:w为v的孩子结点

      k为v的祖先结点

若(v1,v2)是一条边

low[v1]>visit[v2]的意义:

v1包括v1的子树所连的最早的祖先在v2的子树中

结论:

若low[v1]>visit[v2],则(v1,v2)必为桥

 

举例:

无向图求桥的几种方法(无重边)_第10张图片

图8、样例图

如图8,我们要找到图中所有的桥

无向图求桥的几种方法(无重边)_第11张图片

图9、计算visit数组和low数组的过程

如图9,从结点0开始做DFS,结点左边的数为visit,右边的数为low,所得出visit的顺序和low的顺序由上图的蓝色箭头所示

无向图求桥的几种方法(无重边)_第12张图片

图10、low大于visit的结点

如图10,绿色箭头所示的low都大于visit,所以所对应的边都为桥

 

时间复杂度分析:

邻接表一次DFS的复杂度为O(n+e)

 

稀疏图:O(n)

稠密图:O(n²)

数据:

无向图求桥的几种方法(无重边)_第13张图片

图11、Tarjan算法稀疏图数据

由图11可得:在稀疏图中,Tarjan算法的增长符合O(n),而且它的速度超过了前面所提出的所有算法,时间复杂度达到线性

无向图求桥的几种方法(无重边)_第14张图片

图12、Tarjan算法稠密图数据

由上图可得:在稠密图中,Tarjan算法的增长符合O(n²),但仍然是比前面所提过的所有算法快

你可能感兴趣的:(算法分析)