强连通分量分解详解 超级详细

2023-05-16

(写的有点小多,慢慢看,会有收获的)
(1)
首先我们得了解,什么是强连通?
如果在一个有向图顶点子集内,任取两个点 u 和 v ,都能找到一条路径从 u 到 v ,则称该子集为强连通

(2)
其次我们得了解,什么是强连通分量?
如果我们在一个强连通的顶点集合内,加入其他其他任意顶点集合后,它都会变得不再是强连通的,则称该顶点集合为强连通分量

(3)
最后我们得了解,什么是强连通分量分解?
任意有向图都可被分解成若干个不相交的强连通分量(这个不相交,指不同分量中顶点都是不同的),这就是强连通分量分解

注意:我们一般是对有向有环图进行强连通分量,因为有向无环图中,没有强连通分量,无向图中,所有顶点集是一个强连通分量,这种分解没有意义

(4)
那我们怎么进行强连通分量分解?

我们首先进行一次 dfs ,选取任意顶点作为起点,遍历所有尚未访问过的顶点,并在回溯前给顶点标号(后序遍历),对剩余未访问过的顶点,不断重复上述过程
这次的标号主要是为了使越接近图的尾部,顶点的标号越小,为后续操作做铺垫

怎么标号?
我们可以建立一个 vector 容器,这样我们将越接近图的尾部的,越先放入

为什么可以从任何顶点开始?
因为我们是把尾部最先放入。不管我们从哪个点开始遍历,都能遍历到当前剩余顶点集当中,最接近尾部的点,所以不管我们从哪里遍历,都能将该点及该点后面的所有点正确放入。
例如我们按 1 2 3 号顶点的顺序开始遍历,那么我们放入的点,就是圈起来的部分。
很容易看出不管从哪个点开始,都能正确完成操作
请添加图片描述

为什么需要后序遍历?(即先向下递归,回溯时在放入 vector)
因为我们是越接近图的尾部,越先放入。
如果是前序遍历就相当于越接近头部越先放入,这样会出错,因为我们从任意顶点开始遍历,比如我们按 1 2 3 的顺序进行遍历,这样我们先放的相当于是 顶点1 ,而顶点 1 并非头部,这样就会出错

我们再进行一次 dfs ,先将所有边反向,然后以标号最大的顶点为起点进行 dfs ,每次 dfs 所遍历的顶点集合就构成了一个强连通分量,拿个数组保存以下各个点属于哪个强连通分量即可

反向,其实就是记录边的时候多记录一条反向边
从标号最大的开始遍历,其实就是将 vector 从后向前遍历一次

这个的思路是这样的:
因为我们是按从头部到尾部遍历,所以我们正在遍历的只有两种情况
例:如果我们遍历到 顶点1 ,此时没有遍历过的可能是 ”旁边“ 的,或者 “后面” 的
(阴影的相当于已经遍历过)
对于“旁边”:由于上游的点已经遍历过,所以旁边的点递归不到,所以不用考虑
对于“后面”:假设 顶点v 在 顶点u 的“后面”,因为在“后面”,所以有条 u 到 v 的路径,如果把边反向后,仍然 顶点u 有路径到达 顶点v ,相当于在正向图中有一条 v 到 u 的路径,证明 u 到 v 连通

请添加图片描述

代码如下:

#include <iostream>
#include <stdio.h>
#include <vector>
#include <string.h>
using namespace std;
vector<int> data[10005];
vector<int> rdata[10005];
vector<int> flag;
int used[10005];
int kind[10005];
void add_edge(int i, int j)
{
    data[i].push_back(j);
    rdata[j].push_back(i);
}
void dfs(int v)
{
    used[v] = true;
    for(int i = 0; i < data[v].size(); i++)
    {
        if(!used[data[v][i]])
        {
            dfs(data[v][i]);
        }
    }
    flag.push_back(v);
}
void rdfs(int v, int k)
{
    used[v] = true;
    kind[v] = k;
    for(int i = 0; i < rdata[v].size(); i++)
    {
        if(!used[rdata[v][i]])
        {
            rdfs(rdata[v][i], k);
        }
    }
}
int scc()
{
    memset(used, false, sizeof(used));
    for(int i = 0; i < N; i++)
    {
        if(!used[i]) dfs(i);
    }
    memset(used, false, sizeof(used));
    int num = 0;
    for(int i = flag.size() - 1; i >= 0; i--)
    {

        if(!used[flag[i]])
        {
            rdfs(flag[i], num);
            num++;
        }
    }
	return num
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

强连通分量分解详解 超级详细 的相关文章

  • 尚硅谷hadoop3.x集群配置笔记及常见错误解决方式

    1 搭建集群准备工作 总体流程 准备3台客户机 xff08 关闭防火墙 静态IP 主机名称 xff09 安装JDK 配置环境变量 安装Hadoop 配置环境变量 配置集群 单点启动 配置ssh 群起并测试集群 一 模板虚拟机的搭建 配置要求
  • Centos 7系统下NTP时间同步服务配置

    NTP分为服务器端与客户端 xff08 自己选择某一台机器为服务器端 xff0c 其他机器则为客户端 xff09 xff0c 其中 xff0c 客户端通过向服务器端发送时间同步请求实现整个集群的时间同步 具体操作步骤如下所示 xff1a 1
  • EduCoder-程序设计技术R(第四部分循环结构程序设计1)- 第5关:求sn=a+aa+aaa+aaaa+......的值

    大家好鸭 x1f60e xff0c 前几期的EduCoder题解 xff0c 阅读量超过了之前的好多文章 xff01 谢谢大家的阅读 如果题目AC的话 xff0c 求一个免费的赞噢 x1f47b 如果有编程相关的问题 xff0c 可以一起交
  • 和风天气获取天气情况

    和风天气api xff08 实时天气 xff09 https dev qweather com docs api weather weather now 控制台 https console qweather com apps 1 进入控制台
  • Java习题练习:组队

    目录 题目描述 思路 其他真题 题目描述 作为篮球队教练 你需要从以下名单中选出1 号位至5 号位各一名球员 组成球队的首发阵容 每位球员担任1 号位至5 号位时的评分如下表所示 请你计算首发阵容1 号位至5 号位的评分之和最大可能是多少
  • 基于朴素贝叶斯分类器的西瓜数据集(实战)

    最近刚开始学习机器学习中的朴素贝叶斯分类器 xff0c 用西瓜数据集做了一下 xff0c 最后结果预测正确率75 xff0c 其中运用到的python语法并不复杂 xff0c 适合小白观看 目录 朴素贝叶斯分类器思想的自然语言描述 xff1
  • Golang将密码盐加密

    代码地址 xff1a https gitcode net m0 51510236 go password 首先我们来初始化一个项目 go mod init go password golang密码加密我们可以使用 golang org x
  • Spring使用SpringJUnit4ClassRunner时出现java.lang.NoSuchMethodError错误

    报错情况如下 xff1a java lang NoSuchMethodError org springframework core annotation AnnotatedElementUtils getAnnotationAttribut
  • 自己动手搭建网站:electerm远程连接云服务器,部署环境并发布第一个静态页面

    上篇写了云服务器和域名的选购 xff0c 这篇接上篇 xff0c 记录一下如何远程连接云服务器 xff0c 并发布第一个静态网页 xff0c 环境部署在另一篇博文里 xff1a Linux xff08 CentOS7 xff09 下配置jd
  • 解决IDEA报错Failed to start bean ‘documentationPluginsBootstrapper‘

    前言 白嫖容易 xff0c 创作不易 xff0c 若以下方案解决了问题烦请点赞支持一下 xff08 关注一下更好 xff09 在使用IDEA做项目时使用了Swagger进行接口文档的处理 swagger 使用的版本为2 9 2 xff0c
  • C语言%d输出的不同形式

    d就是普通的输出 2d是将数字按宽度为2 xff0c 采用右对齐方式输出 xff0c 若数据位数不到2位 xff0c 则左边补空格 2d是将数字按宽度为2 xff0c 采用左对齐方式输出 xff0c 若数据位数不到2位 xff0c 则右边补
  • latex常用语法

    字母表 字母上面的上标输入方法 xff0c 如右图所示 xff0c 如 bar a 表示字母a头上有一横线 小写希腊字母的输入方法 xff0c 如右图所示 xff0c 大写希腊字母的输入方法 xff0c 如右图所示 xff0c 大写希腊字母
  • Centos 7 内核升级

    一 升级至最新版本内核 1 升级系统包 xff0c 命令如下 yum update y 2 升级内核 xff0c 命令如下 rpm import http www elrepo orq RPM GPG KEY elrepo orq rpm
  • Win11安装Android子系统

    目录 一 获取安卓子系统安装包 二 安装Hyper v 三 运行Android安装包 四 安装组策略编辑器 五 配置Android环境 六 安装安卓apk格式app 一 获取安卓子系统安装包 百度云盘获取包 链接 xff1a https p
  • python-切割字符串成为列表(split函数)

    split函数切割字符串成为列表 在python的input时 xff0c 我们接收都是string类型 information span class token operator 61 span span class token buil
  • MyBatis实现分页查询

    目录 一 基于注解的简单分页查询 1 定义对象 2 Mapper接口 3 Controller类 4 功能实现 二 基于注解的较复杂分页查询 1 定义shop实体类和page分页类 2 Mapper接口 3 Controller类 4 功能
  • python 读取word表格中的表格

    解决方案 xff1a 在网上没有找到可行的嵌套表格内容读取方法 查看python docx包源代码找到以下两种解决方案 xff1a 方案一 xff1a 按行列读到单元格后再取tables xff0c 此处table cell tables值
  • sublime配置C/C++并调试

    文章目录 前言1 工具准备1 1 sublime的安装1 2 MinGw的安装和配置 2 开始配置2 1 MinGw路径放进环境变量2 2 sublime的配置 3 开始使用3 1 运行代码3 2 调试代码 前言 本文主要讲关于sublim
  • 洛谷P1025 [NOIP2001 提高组] 数的划分(DP)

    题目描述 将整数 n n n 分成 k k k 份 xff0c 且每份不能为空 xff0c 任意两个方案不相同 xff08 不考虑顺序 xff09 例如 xff1a
  • 【Rust深入浅出-5】拓展数据类型

    Rust深入浅出 5 拓展数据类型 第一章Hello World 第二章 变量和基本数据类型 第三章 运算符 第四章 类型转换 第五章 拓展数据类型 文章目录 Rust深入浅出 5 拓展数据类型前言slice切片tuple元组索引match

随机推荐

  • sort 函数排序之cmp浅析

    1 一般来说 xff0c sort可对整型和浮点型数据进行排序 xff0c 排序从小到大 xff0c 如果需要变为从大到小 xff0c 那么我们可以定义一个cmp函数 xff0c 定义如下 xff1a bool cmp int x int
  • 魔导师晨拥

    链接 xff1a 登录 专业IT笔试面试备考平台 牛客网 来源 xff1a 牛客网 魔导师晨拥是 炉石传说 中的一张传说卡牌 魔导师晨拥的英雄技能为初始造成 222 点伤害 xff0c 如果恰好消灭某个随从 xff0c 则伤害永久增加 11
  • Royal TSX常见问题:解决远程桌面(RDP)连接错误

    Royal TSX mac破解版是一款帮助用户管理桌面的Mac桌面管理软件 xff0c Royal TSX for mac为你提供方便安全的访问远程系统 Royal TSX专为服务器管理员 系统工程师 开发人员和IT信息工作者开发设计 xf
  • 解决jupyter notebook :No module named ‘tensorflow‘ 及python.exe无法找到入口问题及500 : Internal Server Error

    目录 jupyter notebook ModuleNotFoundError No module named 39 tensorflow 39 问题 可能性1 xff1a tensorflow版本与python版本不匹配 可能性2 xff
  • Ceph安装步骤1——基础Ceph集群安装

    一 基础环境 本文所搭建环境为Centos 7 内核4 17版本 xff0c 安装Ceph版本为luminous 一共配置三台机器 xff0c 每台机器的IP地址和主机名称分别为 xff1a 192 168 1 131 ceph admin
  • 远程桌面--某些设置由你的组织管理

    解决某些设置由你的组织管理 在cmd的运行里输入 gpedit msc 选择 计算机配置 gt 选择 管理模块 gt 选择 Windows组件 gt 选择 远程桌面服务 gt 选择 远程 桌面会话主机 gt 选择 连接 gt 右击 允许用户
  • 数据结构--第三章--栈和队列--知识点回顾

    第三章 栈和队列 一 基本知识点 1 栈 队列和线性表的异同 2 顺序栈的基本运算算法设计 3 链栈的基本运算算法设计 4 顺序队的基本运算算法设计 5 环形队列和非环形队列的特点 6 链队的基本运算算法设计 7 利用栈 队列求解复杂的应用
  • 实验四 SQL连接查询

    一 实验目的 xff1a 掌握SQL连接查询语句 二 实验内容和主要步骤 xff1a 查询每个学生及其选修成绩的情况 select sno cno Grade from sc 分别用左外连接和右外连接实现查询所有学生信息及其选修成绩的情况
  • wsl+opencv——清除旧版并安装新版,实测有效

    写在前面 我用的是cmake方式编译安装的opencv xff0c 但一直弄不好contrib这个东西 xff0c 索性先不用老版本的opencv我把源文件都删掉了 xff0c 没法用网上的一些方法make uninstall 卸载清除旧版
  • JAVA编程——父子类

    编程需求 需求如下 xff1a 编写父类People xff0c 子类Student继承自People类 父类People具有姓名 xff0c 性别 xff0c 年龄等性质 xff0c 还具有吃和说的行为 子类Student继承父类Peop
  • 部署zabbix6.2

    zabbix6 2安装步骤 配置阿里云源 注意本机的操作系统的centos8 span class token punctuation span root 64 localhost span class token operator spa
  • zabbix功能介绍

    1 zabbix介绍 zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案 zabbix能监视各种网络参数 xff0c 保证服务器系统的安全运营 xff1b 并提供灵活的通知机制以让系统管理员快速定位
  • haproxy部署安装

    haproxy简介 HAProxy是一个使用C语言编写的自由及开放源代码软件 xff0c 其提供高可用性 负载均衡 xff0c 以及基于TCP和HTTP的应用程序代理 HAProxy特别适用于那些负载特大的web站点 xff0c 这些站点通
  • KVM虚拟化介绍和安装使用方法

    一 KVM虚拟化介绍 虚拟化 xff1a 在一台计算机上虚拟出多个逻辑的计算机 xff0c 而且每个逻辑计算机 它可以是不同操作系统 虚拟化技术 xff1a 可以扩大硬件容量 xff0c 单个cpu模拟出多个cpu并行 xff0c 允许一个
  • nginx反向代理与负载均衡以及高可用

    nginx反向代理介绍 nginx通常被用作后端服务器的反向代理 xff0c 这样就可以很方便的实现动静分离以及负载均衡 xff0c 从而大大提高服务器的处理能力 nginx实现动静分离 xff0c 其实就是在反向代理的时候 xff0c 如
  • Ceph 配置URL访问s3 Bucket

    一 创建json文件 xff0c 用于编辑policy xff0c 文件内容如下 xff08 Version并不重要 xff09 xff0c Action存在多种选择 如步骤三所示 xff0c 并且允许同时选择多个 xff0c 本文只是通过
  • nginx做负载均衡服务器,配置动静分离

    nginx做负载均衡服务器 xff0c 配置动静分离 1 题目要求 xff1a 后端RS服务器 台部署LNMP nginx1 22 43 mysql8 0 43 php8 1 xff0c 台部署 httpd 要求nginx和php使 编译安
  • 常用自动化运维工具简介和Ansible安装

    自动化运维工具 Puppet Puppet是历史悠久的运维 具之 它是 种基础架构即代码 xff08 IaC xff09 具 xff0c 使 户可以定 义其 基础架构所需的状态 xff0c 并使系统 动化以实现相同状态 Puppet可监视
  • Python之变量、数据类型、类型转换、运算符

    Python学习笔记2022 1 10 pycharmSettingsFont 设置字体字形 大小 行距Keymap 设置快捷键project 变量 xff0c 容器 格式 xff1a 变量名 61 值变量名命名规范 xff1a 数据类型i
  • 强连通分量分解详解 超级详细

    xff08 写的有点小多 xff0c 慢慢看 xff0c 会有收获的 xff09 xff08 1 xff09 首先我们得了解 xff0c 什么是强连通 xff1f 如果在一个有向图顶点子集内 xff0c 任取两个点 u 和 v xff0c