先给出一些定义:
Num(v):记录第几个被visited的顶点
Low(v):(我的理解)记录所在环路的顶点(因为是环路顶点最先访问的,所以也是最小的)
articulation point:下图中的C,D,因为环路(或者树)G,D-E-F分别由C,D连接的
某个顶点V是 articulation point 的关键是 v一些孩子顶点w,并使得 low(w)>= num(v);可以自己观察一下
如下图
![](https://i-blog.csdnimg.cn/blog_migrate/0ecd964b922aced5ec590025d24219d1.png)
从A开始进行深搜,那么就会有下面的树,
虚线的是back edge:深搜的查到已经访问过的顶点的路线(不是实际连接的)
实线的是tree edge:深搜的实际路线
顶点字母旁边的是Num(v)/Low(v)
下图中可见有Num(v)的定义可以知道访问的路径是A-B-C-D-E-F-G;
同时由Low(v)的定义可以看到,环:A-B-C-D,都是Low(v)=1,A(1)是顶点
环:D-E-F,都是Low(v)=4,D(4)是顶点
非环(特殊):G, Low(v)=7
![](https://i-blog.csdnimg.cn/blog_migrate/8242b7579a9a255ba2ad18df30ff941c.png)
对于Low(v)给出书本上的介绍:
low(v) is the minimum of:
num(v) -->使用于第一个顶点,和没有边的顶点
the lowest num (w) among all back edges(v,w) -->low(v)=min(num(w),low(v)),使用于有back edge的顶点
the lowest low(w) among all tree edges(v,w) -->low(v)=min(low(w),low(v)),使用于 tree edge 的顶点
求num(v)和low(v)的伪代码如下
struct vertex
{
bool visited=false;
int num;
int low;
struct vertex *parent=null;
}
//graph 中有一个counter,初始值为1
void graph::assignNum(vertex V)
{
v.num=counter++;
v.visited=true;
for each vertex w adjacent to v:
if(w.visited==false)
{
w.parent=v;
assignNum(w);
}
}
void graph::assignLow(vertex v)
{
v.low=v.num; //rule 1
for each w adjacent to v
{
if(w.num>v.num) //forward edge
{
assignLow(w);
//if(w.low>=v.num)
// cout<<v<<"is an aritculation point"<<endl;
v.low=min(v.low,w.low); //rule 3
}
else
if(v.parent !=w) //back edge
v.low=min(v.low,w.num); //rule 2
}
}