首页 > 其他分享 >tarjan学习笔记

tarjan学习笔记

时间:2023-09-25 17:22:06浏览次数:41  
标签:tarjan 遍历 belong 连通 笔记 学习 dfn low 节点

tarjan学习笔记

0.前置知识

  • 强连通图

    在一个有向图中,若从任意一点可以到达其他所有点,则称之为强连通图

  • 强连通分量(SCC)

    一个图中的极大强连通性质子图(强连通图的强连通分量是它本身)

    \(\small {极大强连通子图指一个不能加入另外的点的强连通子图(一个强连通子图可能包含一个或多个小的强连通子图)}\)

  • dfn(时间戳)

    在对图的遍历中,各个顶点被遍历的顺序( \(dfn[i]\) 表示节点 \(i\) 第几次被遍历到)

  • low(追溯值)

    可以理解为,在一个节点存在的路径中,最小的 \(dfn\) 值( \(low[i]\) 表示在节点 \(i\) 存在的路径中,最小的 \(dfn\) 值)

  • 搜索树

    在一张连通图中,所有的节点以及发生递归的边共同构成一棵搜索树。如果这张图不连通,则构成搜索森林。
    tu

    如图 从lrb博客上扣下来的

    • 搜索树上的边,称为 树边(绿色)。
    • 从祖先指向后代的非树边,称为 前向边(蓝色)。
    • 从后代指向祖先的非树边,称为 返祖边(黄色)。
    • 从子树中的节点指向另一子树节点的边,称为 横叉边(红色)。

1. tarjan求有向图强连通分量

  • 强连通分量判定法则

    其实是求一个节点属于哪个强连通分量

    • \(low\) 的更新方式

      设 当前访问的节点为 \(x\), \(x\) 能到达的点为 \(y\)

      • 初始化 dfn[x]=low[x]=++tot

      • 若 \(y\) 未被遍历到,则该边为树边,递归访问 \(y\) , 因为 \(low\) 的性质,令low[x]=min(low[x],low[y])

      • 若 \(y\) 被遍历过且在栈中,则该边为返祖边或横叉边(存疑),因为 \(low\) 的性质,可以回到 \(x\),令low[x]=min(low[x],low[y])

    • 主要判断方式

      dfn[x]==low[x] 可以理解为 节点 \(x\) 能返回到最早的节点就是 \(x\) 本身,则节点 \(x\) 到 \(s.top()\) 内的所有节点为一个强连通分量。

    • 常用变量

      cnt:强连通图数量

      dfn[]:节点 \(i\) 第几次被遍历到

      low[]:在节点 \(i\) 存在的路径中,最小的 \(dfn\) 值

      belong[]:节点 \(i\) 属于第几个强连通图

      inStack[]:节点 \(i\) 是否在栈中

      tot:当前已有几个节点被访问

    • 代码实现

    inline void tarjan(int x){
        dfn[x]=low[x]=++tot;
        s.push(x);
        inStack[x]=1;
        for(int i = Head[x];i;i=Next[i]){
            int y=Ver[i];
            if(!dfn[y]){
                dfs(y);
                low[x]=min(low[x],low[y]);
            }
            else 
                if(inStack[y])low[x]=min(low[x],low[y]);
        }
        if(dfn[x]==low[x]){
            cnt++;
            while(s.top()!=x){
                belong[s.top()]=cnt;
                inStack[s.top()]=0;
                s.pop();
            }
            inStack[x]=0;
            belong[x]=cnt;
            s.pop();
            
        }
    }
    
  • 缩点

    因为一个节点只属于一个强连通分量,所以对于一些问题,我们可以将一个强连通分量看做一个点。

    即若存在有向边 x->y,若 belong[x]!=belong[y] 则建立一条边 belong[x] -> belong[y]。

    • 代码实现
    for(int i = 1;i <= n;i++){
        for(int j=A.Head[i];j;j=A.Next[j]){
            int y=A.Ver[j];
            if(belong[i]!=belong[y]){
                A_.add(belong[i],belong[y]);
                outp[belong[i]]++;
            }
        }
    }
    

    \(\small{ps:A,A\_ 为封装的链式前向星。}\)

标签:tarjan,遍历,belong,连通,笔记,学习,dfn,low,节点
From: https://www.cnblogs.com/2k3114/p/17728382.html

相关文章

  • 模式识别与机器学习——生成式分类器 课程笔记
    有监督学习:从有标记的数据中学习推断函数目标函数:\(Y=f(x)\)或\(P(Y|X)\)注意:条件概率用小写p表示,先验概率用大写P表示。贝叶斯判别原则给定观测值X,判断其属于\(\omega1\)类还是\(\omega2\)类,最小化误差概率条件下,\(P(\omega1|X)>P(\omega2|X)\)则判断成\(X\in\omega1\),......
  • 《梦断代码》阅读笔记01
    1、与其他的书籍很不同的一点是:这本书有第0章而第0章有这么一句话,也是将我这两年来学习技术的心理状态给描绘了个大概:“helloworld”程序一无所用,但足以蛊惑人心,多少软件雄心勃勃,但最终未结善果。不得不承认的一点是,我当初刚开始使用IDEA编程工具学习Java的时候,坚持学习下去......
  • 计算机视觉:从图像识别到深度学习
    ......
  • 《Java核心技术卷1》学习笔记汇总
    前言转部门了,而且换语言了,开始写接口了,虽然也会用到CPP,但是主要语言是JAVA,因此从零开始学JAVA吧。目录Java程序设计描述Java程序设计环境Java的基本程序设计结构对象与类继承接口、lambda表达式与内部类异常、断言和日志泛型程序设计集合图形用户界面程序设计Swing用户界面组件并发......
  • 可信而可靠,关于Rust 的学习
    最早接触到Rust是在几年前的一次技术大会上,黄东旭说TiKV是用Rust语言编写的,引起了我的一些兴趣,但只是保持关注而已。我一直认为每一种编程语言都有着各自的典型应用领域,也有着各自的编程范式,没有最好的编程语言(参见《PHP是最好的编程语言吗?》),但存在最适合当前的问题领域的编......
  • GraphMAE阅读笔记
    GraphMAE阅读引言在摘要里,本论文提出了自监督学习有着巨大的潜力自监督学习又分为对比学习和生成学习目前比较成功的是对比学习,因为在对比学习中,有高质量的数据增强以及可以通过额外的策略来稳定训练过程而对于生成式的自监督学习,它们旨在重建数据本身的特征和信息,对图来说,图......
  • mysql学习
    mysql0.数据库常见概念0.1概念数据库:英文单词DataBase,简称DB。按照一定格式存储数据的一些文件的组合。顾名思义:存储数据的仓库,实际上就是一堆文件。这些文件中存储了具有特定格式的数据。数据库管理系统:DataBaseManagement,简称DBMS。数据库管理系统是专门用来管理......
  • 深度学习之“智能标注”
    深度学习之“智能标注”,基于视觉大模型,降低标注工作量、提升标注效率与标注质量,详情参见https://docs.neurobot.co/zh_CN/latest/CreateAModel/labelingAssistant/......
  • 《软件需求十步走》阅读笔记
    软件需求是什么?是客户最基本的要求,是开发人员如何针对开发的基准,若软件开发没有了这一步,也就失去了此次开发的必要性,也就如同做了无用功。有需求的存在,对客户、开发团队双方来言是互利的存在,所以我们作为软件工程的学生,自当做好对需求的正确、准确分析。软件需求是软件项目和产品......
  • C++学习后感
    1. C++中的new和delete分别用来分配和释放内存,它们与C语言中malloc()、free()最大的一个不同之处在于:用。构造函数和析构函数对于类来说是不可或缺的,所以在C++中我们非常鼓励使用new和delete。析构就是清除空间,构造就是初始化。2.对于一个存在着标准输入输出的C++控制台......