我不会连通性问题
Part1
割点,桥,强连通分量,双连通分量四个的代码实现很容易混淆,简要记录一下写法。
强连通分量
我们分类讨论三种边:
- 没有被搜索过的:访问,然后将 \(low_v\) 回传更新 \(low_u\)。
- 访问过,在其他的强连通分量里:舍去
- 访问过,在同一个强连通分量里:用 \(dfn_v\) 更新 \(low_u\)。
如果 \(low_u=dfn_u\) 就代表这个强连通分量结束了。
def tarjan(u):
更新dfn,将low设为dfn,将 u 加入栈
搜索可以联通到的所有结点 v:
如果没有被搜索过:
tarjan(v),low_u<-min(low_u,low_v)
如果在栈里:
low_u<-min(low_u,dfn_v)
如果 dfn_u=low_u:
栈为一个强连通分量,清空栈
边双连通分量
还是分类讨论三种边:
- 没有被搜索过的:访问,然后将 \(low_v\) 回传更新 \(low_u\)。
- 访问过,在其他的双连通分量里:舍去
- 访问过,在同一个双连通分量里:用 \(dfn_v\) 更新 \(low_u\)。
如果 \(low_u=dfn_u\) 就代表这个强连通分量结束了。
def tarjan(u,last_edge):
更新dfn,将low设为dfn,将 u 加入栈
搜索可以联通到的所有结点 (v,to_edge):
如果和上一条边重复:退出!
如果没有被搜索过:
tarjan(v,to_edge),low_u<-min(low_u,low_v)
如果在栈里:
low_u<-min(low_u,dfn_v)
如果 dfn_u=low_u:
栈为一个强连通分量,清空栈
点双连通分量
这个注意一下根的问题。
def tarjan(u,fa):
记录 son=0
更新dfn,将low设为dfn,将 u 加入栈
搜索可以联通到的所有结点 (v):
如果没有被搜索过:
son <- son+1,tarjan(v,u),low_u<-min(low_u,low_v)
如果 low_v>=dfn_u:
这是一个点双连通分量
如果在栈里:
low_u<-min(low_u,dfn_v)
如果没有儿子且是根:这是一个点双连通分量
割点和桥
割点和桥分别在点双和边双的交界上,不要再背了。

浙公网安备 33010602011771号