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

SCC学习笔记

时间:2024-04-06 23:35:29浏览次数:19  
标签:low 连通 一个点 点双 笔记 学习 dfn SCC 分量

SCC 学习笔记

好听点的话来说,就是强连通分量。

一个有向图,里面任意两个节点之间可以相互到达,我们把它称为一个强连通分量。

Kosaraju

首先,对于一个强连通的图,显然,他的反图也是一个强连通图。(因为原先 \(A\) 可以到 \(B\),\(B\) 可以到 \(A\),反过来是一样的)

做法是从任意一个点开始,对正图跑一次 \(dfs\) ,记录时间戳,然后根据时间戳从大到小丢到一个栈里面,然后建反图,从栈顶的点开始跑 \(dfs\) ,跑回当前这个点为止,经过的所有点就是这个强连通图里面的点了。(还要打一下 \(vis\) 标记。)

时间是 \(O(n+m)\),跑的很快,很好记。缺点是不能跑割顶(点)。

Tarjan

  • 前置:dfs 树。

以求割顶举例。

割顶:对于图中有一个点 \(x\) ,如果删去它以及其连边后联通块个数增加,那么 \(x\) 即割顶。

先预处理出来 \(dfn\) 序,核心是求一个 \(low\) 数组。

\(low_x\):表示从 \(x\) 往上走能连接上最早的祖先的编号。

\(low\) 的计算过程是:

  • \(low_u=min(low_u,low_v)\),也就是从 \(u\) 往儿子走再跳回去,这是对于树边的情况

  • \(low_u=min(low_u,dfn_v)\),注意,这是是 \(dfn_v\)。原因是我至多只能跳一次,如果是 \(low_v\) ,那就是跳多次,跳多次的话,我从中间断的话,他就不能再到 \(low_v\) 了,就不合法。这是对于反边的情况

就比如这里。\(low_5=3\) 而不是 \(1\),原因是如果等于 \(1\) 的话,把 \(3\) 断掉就不能到 \(1\) 了,就不合法。

然后其实就是各种变形就求出不一样的东西来。

比如说割顶,当 \(dfn_u \le low_v\) 时,\(u\) 就是割顶,也就是儿子没有第二条路到当前节点以上,那么断了这个点儿子(及其子树)就到不了当前节点以上,那就是不连通了。

如果 \(dfn_u<low_v\),该边即割边(桥)。

缩点

强连通分量一个应用。

就是把在一个图内的强连通分量“缩”成一个点,这样可以减少遍历的次数。

在跑 Kosaraju或者 Tarjan 的时候,我们对每一个点记录一个 \(id\),表示他属于哪一个强连通分量的集合里面。(对每个集合标号)

然后枚举原来图里面所有的边,如果两个点的 \(id\) 不同,说明这两个强连通分量有边可以到达,然后连边即可。

缩点完之后就是图就是 DAG了。那就可以在上面跑 \(dp\)。

边双连通分量/点双连通分量

  • 点双连通分量:

定义:任意两个点都能有两条点不重复的路径的无向图就是点双连通分量。

首先就是,点双里面必然没有割点。

如果有的话,桥两端的两个端点只有一条路径能到达,不符合定义。

所以我们只用维护一个栈,遇到割点的时候直接弹出栈里面(非当前割点儿子)的点就是一个点双。

  • 边双连通分量:

定义:任意两个点都能有两条边不重复的路径的无向图就是点双连通分量。

相同的,边双里面没有桥。(不然端点一样不符合性质。)

所以我们考虑找到所有的割边并删去。然后对剩下的连通块进行染色即可。

标签:low,连通,一个点,点双,笔记,学习,dfn,SCC,分量
From: https://www.cnblogs.com/JuneFailue/p/18118179

相关文章

  • 生成树学习笔记
    最小生成树学习笔记代码合集很好,这还是一篇复习笔记。考虑这么一个问题,给出一张无向图,有\(n\)个点,\(m\)条边,边有边权,要你找\(n-1\)条边,使得这\(n\)个点联通且边权和最小。Kruskal首先,我们先把边权进行排序,然后贪心的加边,把选的边所带的点加到一个集合里面。如果\(x......
  • 单调栈 and 单调队列学习笔记
    单调栈and单调队列学习笔记本文均以维护单调递增的栈/队列举例。本篇代码合集以后在写动态规划单调队列/单调栈优化的时候,这两个东西会合并。单调栈本质上就是模拟。假设要维护一个单调递增的栈,那么对于一个元素进来了,在栈顶的所有比他小的数我全部都要踢出去,不然就不满足......
  • 并查集学习笔记
    并查集学习笔记本质上还是一个复习笔记。考虑这样一个问题:给出\(x,y\),合并\(x,y\)所在集合。给出\(x,y\),查询\(x,y\)是否在同一集合内。我们把集合当成一棵树,两个点有连边就表示他们在同一个集合内。这棵树的根节点就是这个集合的“老大”,也就是这个集合里面的......
  • Docker学习笔记(三)Dockerfile指令详解
    文章目录FROM指定基础镜像RUN执行命令COPY复制文件ADD高级文件复制CMD容器启动命令ENTRYPOINT入口点ENV设置环境变量ARG构建参数VOLUME定义匿名卷EXPOSE声明端口WORKDIR指定工作目录USER指定当前用户HEALTHCHECK健康检查ONBUILD构建触发器LABEL添加元数据......
  • C语言学习笔记--(2)基础语法
    我先写点,我不太擅长写,所以各位有问题可以评论说,我看到一定改一.C语言编程的格式    我们可以先看一个关于C语言的基础实例下面是一个简单的C语言程序,用于计算购买商品的总价,并根据折扣计算最终支付金额。#include<stdio.h>//计算购买商品的总价floatcalculat......
  • 后端学习记录~~JavaSE篇(day03-流程控制语句-上)
    if...else与Switch...case语句一、表达式和语句表达式:(1)变量或常量+运算符构成的计算表达式(2)new表达式,结果是一个数组或类的对象。(3)方法调用表达式,结果是方法返回值或void(无返回值)。语句:(1)分支语句:if...else,switch...case(2)循环语句:for,while,do...while(3)跳转语句:brea......
  • React 学习之 Hello World
    React学习之HelloWorldReact简介React是一个用于构建用户界面的JavaScript库,由Facebook开发并维护。React通过声明式的方式来构建UI,使得代码更易于理解和测试。React的核心概念包括组件(Component)和虚拟DOM(VirtualDOM)。组件:在React中,UI被构建为组件的集合。组件是封装了HTM......
  • 2-SAT 学习笔记
    2-SAT学习笔记P4782【模板】2-SAT2-SAT问题模型:构造bool变量\(x_1,x_2...x_n\),使得满足一些限制一对\(x_1\)和\(x_2\)取值的条件合法。很显然根据Floyd传递闭包可以做到\(O(n^3+m)\),但不太行。有\(O(n+m)\)的做法,发现对于每个条件是要我们选择一种取值(选择就很......
  • [笔记]数位dp例题及详解(更新中)
    数位dp的定义引自洛谷日报#84:求出在给定区间\([L,R]\)内,符合条件\(f(i)\)的数\(i\)的个数。条件\(f(i)\)一般与数的大小无关,而与数的组成有关。由于是按位dp,数的大小对复杂度的影响很小。由于数位dp状态的上下文信息比较多,所以一般用记忆化搜索实现,而非递推。P4999烦人的数......
  • 第七周后端学习报告
    CJT的学习报告 本周学习及进展 AOPLogback自定义注解 具体进展使用这三个技术栈实现了日志框架日志框架github地址:cjt666-hhh/sosdDemo(github.com)首先使用AOP技术进行解耦,使得日志框架能够灵活配置到多个方法以及接口,后续对于对于日志框架维护成本降低,仅需修......