Loading

我不会连通性问题

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)
	如果没有儿子且是根:这是一个点双连通分量

割点和桥

割点和桥分别在点双和边双的交界上,不要再背了。

posted @ 2026-02-02 16:12  back_find  阅读(0)  评论(0)    收藏  举报