7.4.4关节点和重连通分量

  • 关节点
    若删去 顶点v 以及 和 v 相关联的各边 之后,将图的一个连通分量分割成 两个或者两个以上的连通分量 ,则称顶点 v 为该图的一个关节点

  • 重连通图
    一个没有关节点的连通图称为重连通图

  • 重连通图的性质
    任意一对顶点之间至少存在两条路径,则在删去 某个顶点 以及 依附于该顶点的各边 时也不破坏图的连通性。
    连通度:若在连通图上至少删去 k 个顶点 才能破坏图的连通性,则称此图的 连通度 为 k。

  • 关节点重连通 在实际中应用较多,
    如一个表示通信网络的图的连通度很高,其系统可靠,无论是哪一站点出现故障或者遭到外界破坏,都不会影响系统的正常工作。

  • 如下图,是连通图,但不是重连通图
    在这里插入图片描述
    图中有 4 个关节点 A、B、D 和 G。
    若删去顶点 B 以及所有依附于 B 的边,G5 就会被分割成 3 个连通分量:
    { A , C , F , L , M , J }
    { G , H , I , K }
    { D , E }
    因此 关节点 也叫作 割点

利用深度优先搜索来求关节点,判断是否是重连通图

在这里插入图片描述
在这里插入图片描述
图 7.20 所示为从顶点 A 出发深度优先搜索遍历 图 G~5~ 所得的 深度优先生成树,图中 实线 表示 树边虚线 表示 回边(即图中但 不在 生成树上的边)。
对树中任一顶点 v 而言,其 孩子结点 为在它之后搜索到的邻接点,而其 双亲结点由回边联结的祖先结点 是在它之前搜索到的邻接点。
1、若生成树的根有两棵或两棵以上的子树,则此根必为关节点。因为图中不存在联结不同子树中顶点的边,因此若删去 根顶点生成树 便变成 生成森林,如上图 7.20 中的 顶点 A
2、若生成树中某个 非叶子顶点v某一棵子树的根该子树中的其他结点 均没有指向 v 的祖先的回边,则 v 为关节点。 因为若删去 v,则其子树和图的其他部分被分割开来,如上图 7.20 中的顶点 B、D 和 G。

判断给叶子结点是否是关节点的算法

  • 引入一个 新的函数 low,由依次 深度优先搜索遍历 便可求得连通图中存在的所有关节点。
    定义 visited[v] 为深度优先搜索遍历连通图时访问顶点 v 的 次序号
    如下
    在这里插入图片描述
    v 是 待判断的结点的标号、在图中的位置。
    w 是 顶点 v 在深度优先生成树上的孩子结点。
    k 是 顶点 v 在深度优先生成树上由回边连接的祖先结点。

  • 判断依据
    若对于某个顶点 v,存在孩子结点 w 且 low [ w ] >= visited [ v ],则该顶点必为关节点。
    因为当w是v的孩子结点时 low[w] >= visited[v] ,表明 w 及其子孙均无指向 v 的祖先的回边,由此 v 是关节点。

判断某个非叶子顶点是否是关节点

  • 连通图G 以 邻接表 作为存储结构
#define MAX_VERTEX_NUM 20

typedef struct ArcNode
{
	int adjvex;  // 该弧所指向的顶点的位置
	struct ArcNode *nextarc; // 指向的下一条弧的指针
	InfoType *info; // 指向该弧相关信息的指针
} ArcNode;  // 表中结点,表示一条弧(也可以是一条边) 

typedef struct VNode
{
	VertexType data;   //顶点信息
	ArcNode *firstarc; //指向第一条依附于该顶点的弧的指针
} VNode, AdjList[MAX_VERTEX_NUM]typedef struct
{
	AdjList vertices;   //存放顶点结点的顺序表
	int vexnum, arcnum; //图的当前顶点数和弧数
	int kind; 			//图的种类,标志
} ALGraph;

void FindArticul(ALGraph G)
{
	count = 1;
	visited[0] = 1;
	for(i=1; i<G.vexnum; i++)
	{
		visited[i] = 0;
	}
	p = G.vertices[0].firstarc;
	v = p->adjvex;
	DFSArticul(G, v);
	if(count < G.vexnum)
	{
		printf(0, G.vertices[0].data);
		while(p->nextarc)
		{
			p = p->nextarc;
			v = p->adjvex;
			if(visited[v] == 0)
			{
				DFSArticul(g, v);
			}
		}
	}
}

void DFSArticul(ALGraph G, int v0)
{
	visited[v0] = min = ++count;
	for(p=G.vertices[v0].firstarc;
			p;
			p=p->nextarc;)
	{
		w = p->adjvex; // w 是 v0 的邻接顶点
		if(visited[w] == 0) // w 未被访问,是 v0 的孩子
		{
			DFSArticul(G, w); // 返回之前求得 low[w]
			if(low[w] < min)
			{
				min = low[w];
			}
			if(low[w] >= visited[v0]) // 此为关节点
			{
				printf(v0, G.vertices[v0].data); 
			}
		}
		else if(visited[w] < min)
		{
			min = visited[w];
		}
	}
		low[v0] = min; // 返回前求得 v0 的值
}
  • 图 G5 中各顶点计算所得 visited 和 low 的函数值
    在这里插入图片描述
  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值