一 、 无 向 图 : \green{一、无向图:} 一、无向图:
目 标 : \red{目标:} 目标:
- 找关节点
- 找关节点对应联通分量
- 找点或边的重联通分量
- 找割边
时间:邻接矩阵O(N^2)、邻接表O(E)
关 节 点 : \red{关节点:} 关节点:去掉该点后,剩余图不是个联通图,剩余联通图的数量为所求联通分量。
基
本
思
想
\red{基本思想}
基本思想,采用一次DFS计算每个点在搜索树中的层级。
维护:
dfn[x]:表示点x在搜索树中搜索次序,依次递增
low[x]:表示点x必须通过子节点路径可以到达的最小层次(最祖先节点)。
subnets[x]:表示去掉点x后的联通图数量
充 要 条 件 : \red{充要条件:} 充要条件:
- 若点x是DFS搜索树的根,则x有至少2个孩子时,x是关节点,联通数量为其孩子数量。
- 若点x非DFS搜索树的根,则x的孩子y,存在low[y] >= dfn[x],则x是关节点,联通数量为满足条件y的数量+1
解 释 : \red{解释:} 解释:
- 若x为根,好理解,当x不是关节点时,DFS时,x一定最多有1个孩子。
- 若x非根,重点解释low[y]>=dfn[x],low[y]表示点y通过向下走的方式可以到达的最祖先的节点z,当这个z还没有x的层级小,即z不是x的祖先,则去掉x后,y不能联系到x的祖先,x是关节点。
如 何 维 护 l o w 和 d f n 数 组 ? \red{如何维护low和dfn数组?} 如何维护low和dfn数组?
DFS向下搜索时,初始化dfn和low数组,dfn和low都等于搜索次序,以后dfn固定不变。
DFS回溯时,更新low数组,low在两种情况中取最小:
- 孩子中low最小的
- 邻接点中dfn最小的
割 边 : \red{割边:} 割边:
当low[y] > dfn[x]时,xy边为割边
点 重 联 通 分 量 : \red{点重联通分量:} 点重联通分量:
另行维护一个栈,DFS正向搜索时,把搜索树边和回边压入栈中,回溯时,若遇到关节点,则弹出边直到遇到关节点与其孩子的边,则这些边组成了一个重联通分量。
回边:非搜索树的边(非科学定义,可自行拓展)
边 重 联 通 分 量 : \red{边重联通分量:} 边重联通分量:
去除割边后,剩下就是边联通图
二 、 有 向 图 : \green{二、有向图:} 二、有向图:
找有向图强联通分量