关节点算法
- 关节点的定义
在连通图当中,对于某个顶点的孩子顶点或其子树中顶点,如果要访问某个顶点的双亲节点或更上级节点,必须经过此顶点,那么此顶点我们称之为关节点。 对于关节点之下的某个子树,这个关节点充当"一夫当关,万夫莫开"的角色。在算法中,关节点可以通过多次深度优先搜或合并的深度优先搜索求得。 - 关节点算法中的基本规则
对于本文中的图,我们抽象出下属几个变量和规则来完成关节点的算法。

对于每个顶点,都具备以下属性:
- num[v]: 通过DFS访问某个顶点的次序,为了方便描述我们定义A为0号元素,以此类推,那么从顶点A开始遍历,num[v]的可能数组为num[0]=1, num[3]=1, num[4]=3, num[5]=4,num[2]=5, num[6]=6; num[1]=7;
- visited[v]: 标记元素v是否被访问,未方位标记为0,已访问标记为1
- low[v]数组,对于某个元素的low[v]的值,取决于下列三类值的递归大小
- num[v] - Rule 1
- the lowest num[w] among all back edges(v,w)- Rule 2
- the lowest low[w] among all tree edges(v,w) -Rule 3
对于num[v],代表节点自身访问次序号,它不考虑任何tree edge 或者 back edge,可以采用先序深度遍历实现;对于num[w]只得是v的某个孩子节点或更下的孩子节点有回边到v的父节点之上的顶点(v的直接父节点不考虑);对于low[w]为在孩子节点中不断搜寻最小的值,逐个孩子进行比较,这里涉及到后续遍历处理完成退出递归后的比较处理,在这个过程中可能也涉及到回边的处理。
- 判断为节点的条件,有两种情况可以认定某个顶点为节点
- 如果根节点有两个或两个以上的独立的子树,那么根节点就是关节点,因为如果移除根节点,那么就会形成两棵独立的子树
- 对于非根节点,如果其low(w)>=num(v), 其中w为v的邻接点,这时候,如果w要回达到v以上的祖先节点,那么v就是必经点,此时v为关节点。如果v为根节点,那么此关系总成立,所以需要进行独立判断。
- 代码实现,本代码采用两个DFS进行遍历,其中第一个DFS求出num数组,第二个DFS进行遍历,求出low数组,同时打印出关节点。在第二个DFS遍历过程中,需要判断(v,w)边的类型,可以利用num数组进行判断,对于tree edge(直接遍历边),num[w]>num[v],对于back edge(回边)num[w]<num[v], 通过比较两个顶点大小,便可判断访问边的基本类型。
/*
@brief,
This function will work out the vertex visiting order via DFS traversal and the order will be kept in the num[s] in the pre-order mode
@param G, Adjacent List Graph
@param s, Starting Search Point
*/
void assign_num(ALGraph G,int s)
{
int v;
int w;
//counter is the global variable to indicate the visiting order
//num is also the global varaible shared in different functions
//visited[] indicate if the vertex had been visited or not
num[s]=counter++;
visited[s]=1;
v = s;
for(w=FirstAdjVex(G

文章介绍了关节点的概念,即在连通图中,必须经过的顶点才能到达其他部分。通过深度优先搜索两次,首先计算访问次序num数组,然后确定low数组,从而识别关节点。算法复杂度为O(|E|+|V|),适用于查找图的结构关键点。
最低0.47元/天 解锁文章
8277

被折叠的 条评论
为什么被折叠?



