算法:Tarjan算法

一 、 无 向 图 : \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数组?} lowdfn

DFS向下搜索时,初始化dfn和low数组,dfn和low都等于搜索次序,以后dfn固定不变。
DFS回溯时,更新low数组,low在两种情况中取最小:

  • 孩子中low最小的
  • 邻接点中dfn最小的

割 边 : \red{割边:}

当low[y] > dfn[x]时,xy边为割边

点 重 联 通 分 量 : \red{点重联通分量:}

另行维护一个栈,DFS正向搜索时,把搜索树边和回边压入栈中,回溯时,若遇到关节点,则弹出边直到遇到关节点与其孩子的边,则这些边组成了一个重联通分量。

回边:非搜索树的边(非科学定义,可自行拓展)

边 重 联 通 分 量 : \red{边重联通分量:}

去除割边后,剩下就是边联通图


二 、 有 向 图 : \green{二、有向图:}

找有向图强联通分量

你可能感兴趣的:(my,algorithm,summary)