连通性+ 1
早在普及组的时候,我们就学会了:
-
DFS(BFS)搜连通块
-
并查集在加边的情况下动态维护连通块(支持离线处理删边)
现在,我问你:
-
我删去一个点/边,判断剩下的图存在原本某两个连通的点现在不连通?
-
我随机删去一条边,判断剩下的图中某两个点是否一定连通?
-
我随机给你一些点,判断其中两两是否互相可达(有向图上)?
第三个问题不是今天这篇文章所讲的范畴,但是其他问题确实可以讲一讲。
我删去一个点/边,判断剩下的图存在原本某两个连通的点现在不连通?
点
形式化定义:有
这个问题可以使用 Tarjan 求解。
Tarjan(谐音太监,虽然其正确中文名为塔杨)通过两个数组来求解:
如果对于
根节点的每一个儿子必然满足条件,所以我们要特判:
根是割点当且仅当根在树上有至少两个儿子。
伪代码:
function() Tarjan(x, fa, rt) does (int)c(0) dfn[x] = low[x] = ++cnt, vis[x] = 1 for(each i \in adj[x]) does when(!vis[i]) then c++ Tarjan(i, x, rt) low[x] sets(\min) low[i] when(x \ne rt \and low[i] \ge dfn[x]) then satis[x] = 1 back on track and when(i \ne fa) then low[x] sets(\min) dfn[i] back on track back on track when(x \eq rt \and c \gt 1) then satis[x] = 1 back on track back on track
边
形式化定义:有
跟点的情况很像,具体看伪代码:
function() Tarjan(x, fa) does dfn[x] = low[x] = ++cnt, vis[x] = 1 for(each i \in adj[x]) does when(!vis[i]) then Tarjan(i, x, rt) low[x] sets(\min) low[i] (note)(没有根的特殊情况) when(low[i] \ge dfn[x]) then satis[i] = 1 (note)(实际上是孩子) back on track and when(i \ne fa) then low[x] sets(\min) dfn[i] back on track back on track (note)(没有根的特殊情况) back on track
我随机删去一条边,判断剩下的图中某两个点是否一定连通?
很简单:
按照上面的方式处理出桥,断掉桥,条件满足当且仅当之后的图中两个点仍然连通。
附录:Tarjan 模板
function() Tarjan(x, fa) does dfn[x] = low[x] = ++cnt, vis[x] = 1 for(each i \in adj[x]) does when(!vis[i]) then Tarjan(i, x) low[x] sets(\min) low[i] and when(i \ne fa) then low[x] sets(\min) dfn[i] back on track back on track back on track
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具