Tarjan 算法(超详细!!)

本文介绍了Tarjan算法用于解决图中的强连通分量问题,通过深度优先搜索构建搜索树,区分横叉边、前向边和后向边,利用时间戳确定连通性。还提供了P1726问题的代码实现,包括寻找最大强连通分量及其成员的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

推荐在 cnblogs 上阅读

Tarjan 算法

前言

说来惭愧,这个模板仅是绿的算法至今我才学会。

我还记得去年 CSP2023 坐大巴路上拿着书背 Tarjan 的模板(CSP2024 也没学会)。虽然那年没有考连通分量类似的题目(2024 也没有)。

现在做题遇到了 Tarjan,那么,重学,开写!

另,要想学好此算法的第一件事——膜拜 Tarjan 爷爷。

再序(upd on 2024.11.4)

这个东西意外成为了我博客下最多人收藏的文章,我在 CSP2024 前重新复习时发现仍然漏洞百出,为了对大家负责我决定重构整篇。

顺带补上边双和点双。

定义

强连通分量

一个图的子图若任意两点之间均有路径可达,则成该子图为原图的强连通分量。

割点

如果一个连通分量内有一个点,把这个点及其邻边删掉后连通分量不再连通而变成了两个连通分量,那么这个点就是割点。下图中点 2 2 2 就是割点。

割边(桥)

与割点定义类似,删除某一边后连通分量不再连通。如下图 ( 2 , 5 ) (2,5) (2,5) ( 5 , 6 ) (5,6) (5,6) 都是割边。

点双连通分量

定义:没有割点的双连通分量。“双连通分量”指任意两点都有两条不同路径可达。

边双连通分量

定义:没有割边的双连通分量。

如何求割点

采用 Tarjan 求割点。思想:在 dfs 时访问到 k k k 点时,图会被点 k k k 分为已访问和未访问两部分。如果 k k k 是割点,那么一定存在没有访问过的点在不经过 k k k 的情况下不能访问到已访问过的点。

这里要用到回溯值 low[u] 表示点 u u u 可以访问到时间戳(dfn[u]=++tim)最小的节点。

根据这些信息来判断割点:

  1. 若当前点是根节点,如果子树数量大于 1 1 1 则说明该点为割点。
  2. 若当前点不是根节点,如果存在一个儿子的回溯值大于等于该点的时间戳(low[v]>=dfn[u]),则该点为割点(因为儿子无法绕过该点去访问时间戳更小的点)。

如何求割边

判断割边的条件是一条边 ( u , v ) (u,v) (u,v)low[v]>dfn[u]。如果相等意味着点 v v v 还可以回到点 u u u,所以不相等意味着连父亲也回不到。如果点 v v v 回不到祖先,也无法绕过 ( u , v ) (u,v) (u,v) 这条边回到父亲,那么 ( u , v ) (u,v) (u,v) 就是割边。

如何求点双

点双模板题

点双是没有割点的双连通分量,一个割点可能属于多个点双,非割点只属于一个点双。那么我们可以在 dfs 的过程中压点入栈,判断到当前点为割点时,就不断弹栈,弹出来的节点都属于一个点双。

注意特判一个点就是一个子图的情况也是点双。

#include<bits/stdc++.h>
using namespace std;

#define int long long

const int N=2e6+5;

int n,m;
int dfn[N],low[N],tim,cnt;
vector<int> G[N],ans[N];
int stk[N],top;

void tarjan(int u,int pa)
{
   
    dfn[u]=low[u]=++tim;
    stk[++top]=u;
    int son=0;
    for(int v:G[u]){
   
        if(!dfn[v]){
   
            tarjan(v,u);
            ++son;
            low[u]=min(low[u],low[v]);
            if(pa==0&&son>1||low[v]>=dfn[u]){
   
                ++cnt;
                while
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值