020-寻找图的关节点-dfs-《算法设计技巧与分析》M.H.A学习笔记

来源:互联网 发布:千牛淘宝商品怎么分类 编辑:程序博客网 时间:2024/05/16 11:14

关节点的定义:

在多于两个顶点的无向图G中,存在一个顶点v,如果有不同于v的两个顶点uw,在uw间的任何路径都必定经过顶点v,则称v为关节点。

一种更形象的说法:

关节点也叫割点,连通图中删去割点会被分割成几个连通分量。

 

我们可以通过dfs来寻找关节点。

基本思路:

在图G上进行一个dfs,遍历过程中对每个顶点v保持两个标号α[v]和β[v]α[v]dfs的深度,β[v]初始化为α[v]在遍历过程中修改为下列几个中的最小值:

1. α[v]

2. α[u],对于每个顶点u,(vu)是回边;

3. β[w],在dfs树中的每条边(vw)。

关节点确定如下:

1. 根是一个关节点当且仅当在dfs树中,它有两个或更多的儿子。

2. 根以外的顶点v是一个关节点当且仅当v有一个儿子w,使得β[w]>=α[v]

 

伪代码:

 


 

 

C++代码:

来自http://www.xuebuyuan.com/1479536.html

#include <cstdio>#include <cstdlib>#define VERTEX_NUM7#define NOT_VISITED 0int dfn;//表示某顶点在深度优先遍历中被访问的顺序void find_articulation(int adj[][VERTEX_NUM], int visit[], int low[]);//寻找图的关节点,并输出void DFS_articulation(int adj[][VERTEX_NUM], int vertex, int visit[], int low[]);//从vertex顶点出发,查找并输出关节点int main(){//无向连通图的邻接表数据,-1表示结束int Adj[VERTEX_NUM][VERTEX_NUM] = {{0, 1, 3, -1},{1, 0, 2, 3, 4, -1},{2, 1, 3, 4, 5, -1},{3, 0, 1, 2, 4, -1},{4, 1, 2, 3, 5, -1},{5, 4, 6, -1},{6, 5, -1}};int low[VERTEX_NUM];//low[]数组的意义见上面的分析int visit[VERTEX_NUM];for (int i = 0; i < VERTEX_NUM; i++)visit[VERTEX_NUM] = NOT_VISITED;//查找图的关节点,并输出find_articulation(Adj, visit, low);system("pause");return 0;}void find_articulation(int adj[][VERTEX_NUM], int visit[], int low[])//visit[i]保存顶点i被访问的顺序{dfn = 1;visit[adj[0][0]] = 1;//设adj[0][0]顶点为生成树的根for (int i = 1; i < VERTEX_NUM; i++)visit[i] = NOT_VISITED;int vertex = adj[0][1];DFS_articulation(adj, vertex, visit, low);if (dfn < VERTEX_NUM)//生成树的根至少有两棵子树{printf("%d  ", vertex);//输出关节点for (int j = 1; adj[0][j] != -1; j++)if (visit[adj[0][j]] == NOT_VISITED)DFS_articulation(adj, adj[0][j], visit, low);}}void DFS_articulation(int adj[][VERTEX_NUM], int vertex, int visit[], int low[]){dfn++;int min = dfn;visit[vertex] = dfn;for (int j = 1; adj[vertex][j] != -1; j++){int w = adj[vertex][j];if (visit[w] == NOT_VISITED){



 

0 0