双连通分量算法

1. 连通图概念

连通图:无向图任意两点之间存在通路。
强连通:有向图(前提)中,任意两点都有至少一条通路,则此图为强连通图。
弱连通图:将有向图的有向边换成无向边得到的图是连通图,则此有向图是弱连通图。

1.1 连通图和强连通图区别

连通图和强连通图的主要区别在于它们处理无向图和有向图的方式。以下是详细介绍:

连通图。 连通图的概念基于无向图,其中如果任意两个顶点之间都存在一条路径,那么整个图被称为连通图。这意味着,从任何一个顶点出发,都可以通过路径到达图中的任何其他顶点。
强连通图。 强连通图的概念则针对有向图,其中不仅要求从顶点vi到顶点vj存在路径,还要求从顶点vj到顶点vi也存在路径,对于所有顶点对vi和vj。这意味着图中不存在方向性的障碍,任意两个顶点之间可以相互到达。
简而言之,连通图关注的是无向图中顶点的连接性,而强连通图关注的是有向图中顶点的双向连接性。

2. Targan强连通分量算法

2.1 基本概念

强连通分量: 在有向图G中,如果两个顶点u,v间(u->v)有一条从u到v的有向路径,同时还有一条从v到u的有向路径,则称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。有向图极大强连通子图,称为强连通分量。
在这里插入图片描述
α \alpha α β \beta β γ \gamma γ 是三个强连通分量。

2.1 DFS遍历

在这里插入图片描述
方式1可以看作前序遍历
在这里插入图片描述
方式2可以看作后序遍历

3. 举例

在这里插入图片描述
回溯,更新$j$
在这里插入图片描述
相同 j j j出栈
在这里插入图片描述
a a a也出栈,单独连通分量。
在这里插入图片描述

4. 代码实现

在这里插入图片描述

#include <bits/stdc++.h>using namespace std;#define M (INT_MAX)
#define PRINT_ARRAY(a,n)    do{for(int i = 0; i < n; i++) cout<<a[i]<<"|"; cout<<endl;}while(0)/**********************************************1 → 0 → 3↑ ↙     ↓2       43 → 4 ← 6 → 2↑↓  ↓ ↗ ↓ ↙↑7 → 5 → 0 → 1
**********************************************/
// #define V (5)
// int g[V][V] = 
// {
//     {0,0,1,1,0},
//     {1,0,0,0,0},
//     {0,1,0,0,0},
//     {0,0,0,0,1},
//     {0,0,0,0,0}
// };#define V (8)
int g[V][V] = 
{ // 0 1 2 3 4 5 6 7  {0,1,0,0,0,0,0,0},{0,0,1,0,0,0,0,0},{1,0,0,0,0,0,0,0},{0,0,0,0,1,0,0,1},{0,0,0,0,0,1,0,0},{1,0,0,0,0,0,1,0},{1,0,1,0,1,0,0,0},{0,0,0,1,0,1,0,0}
};/**********************************************强连通分量 strongly connected component
**********************************************/void tarjan_dfs(int x, int dfn[], int low[], stack<int>& s, bool in_stack[])
{static int time = 1;dfn[x] = low[x] = time++;s.push(x);in_stack[x] = true;for(int y = 0; y < V; y++){if(g[x][y]){if(0 == dfn[y]){tarjan_dfs(y, dfn, low, s, in_stack);low[x] = min(low[x], low[y]);}else if(in_stack[y])low[x] = min(low[x], dfn[y]);}}if(dfn[x] == low[x]){int tmp;do{tmp = s.top(); s.pop();in_stack[tmp] = false;cout<<tmp<<"-";}while(tmp != x);cout<<endl;}
}void scc_tarjan()
{int dfn[V] = {0}, low[V] = {0};bool in_stack[V] = {false};stack<int> s;for(int i = 0; i < V; i++)if(!dfn[i])tarjan_dfs(i, dfn, low, s, in_stack);
}int main()
{scc_tarjan();return 0;
}

参考资料:
https://www.bilibili.com/video/BV19J411J7AZ?p=1&vd_source=63c3682e66febb42e6a271165dd5a13e
https://github.com/xiaoyazi333/data-structure-and-algorithm/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/796356.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

初识二叉树和二叉树的基本操作

目录 一、树 1.什么是树 2. 与树相关的概念 二、二叉树 1.什么是二叉树 2.二叉树特点 3.满二叉树与完全二叉树 4.二叉树性质 相关题目&#xff1a; 5.二叉树的存储 6.二叉树的遍历和基本操作 二叉树的遍历 二叉树的基本操作 一、树 1.什么是树 子树是不相交的;…

计算机网络——37认证

认证 目标&#xff1a;Bob需要Alice证明他的身份 Protocol ap1.0&#xff1a;Alice说"A am Alice" 可能出现的问题&#xff1a; 在网络上Bob看不到Alice&#xff0c;因此Trudy可以简单的声称他是Alice 认证&#xff1a;重新尝试 Protocol ap2.0&#xff1a;Alice…

影院座位选择简易实现(uniapp)

界面展示 主要使用到uniap中的movable-area&#xff0c;和movable-view组件实现。 代码逻辑分析 1、使用movable-area和movea-view组件&#xff0c;用于座位展示 <div class"ui-seat__box"><movable-area class"ui-movableArea"><movab…

【毕业论文】酒店价格采集与可视化查询设计与实现开题报告2000字

酒店价格采集与可视化查询设计与实现开题报告 研究背景 随着互联网技术的飞速发展&#xff0c;人们获取信息的途径越来越多样化。特别是在旅游行业中&#xff0c;消费者对于酒店价格的透明度和实时性要求越来越高。美团、大众点评、抖音等平台作为信息聚合和分享的重要渠道&a…

Flutter开发进阶之错误信息

Flutter开发进阶之错误信息 在Flutter开发中错误信息通常是由Exception和Error表示&#xff0c;Error表示严重且不可恢复的错误&#xff0c;一般会导致程序直接终止&#xff0c;而Exception可以被显式抛出&#xff0c;一般为代码逻辑错误&#xff0c;根据Flutter的解释说Excep…

【opencv】示例-aruco_dict_utils.cpp 计算 ArUco 字典度量

该程序可用于计算 ArUco 字典度量。 要计算考虑翻转标记的指标&#xff0c;请使用 -r 标志。 该程序可用于创建和编写自定义 ArUco 词典。 #include <opencv2/objdetect/aruco_detector.hpp> // 包含aruco marker检测相关功能的头文件 #include <iostream> // 包含…

如何在 Ubuntu 上安装和配置 Tomcat 服务器?

简介&#xff1a;最近有粉丝朋友在问如何在 Ubuntu 上安装和配置 Tomcat 服务器&#xff1f;今天特地写这篇文章进行解答&#xff0c;希望能够帮助到大家。 文章目录 Ubuntu上安装和配置Tomcat的详细步骤Tomcat在Linux环境下的安装与配置一、下载并上传Tomcat压缩包二、启动To…

云架构(三) 防腐层模式

Anti-corruption Layer pattern (https://learn.microsoft.com/en-us/azure/architecture/patterns/anti-corruption-layer) 简单描述 实现一个门面或者适配层在新应用和历史遗留程序之间。在不同的系统之间实现一个门面或者适配层&#xff0c;不需要使用相同的语义。它在不…

961: 进制转换问

【学习版】 【C语言】 #include<iostream>struct SeqList {int top;int len;int* s; };void initStack(SeqList* stack, int len) {stack->s new int[len];stack->top -1;stack->len len; }void push(SeqList* stack, int x) {stack->s[stack->top] …

YOLOv5实战记录05 Pyside6可视化界面

个人打卡&#xff0c;慎看。 指路大佬&#xff1a;【手把手带你实战YOLOv5-入门篇】YOLOv5 Pyside6可视化界面_哔哩哔哩_bilibili 零、虚拟环境迁移路径后pip报错解决 yolov5-master文件夹我换位置后&#xff0c;无法pip install了。解决如下&#xff1a; activate.bat中修改…

.NET8 和 Vue.js 的前后端分离

在.NET 8中实现前后端分离主要涉及到两个部分&#xff1a;后端API的开发和前端应用的开发。后端API通常使用ASP.NET Core来构建&#xff0c;而前端应用则可以使用任何前端框架或技术栈&#xff0c;比如Vue.js、React或Angular等。下面是一个简化的步骤指南&#xff0c;帮助你在…

汇川PLC学习Day4:电机参数和气缸控制参数

汇川PLC学习Day4&#xff1a;伺服电机参数和气缸控制参数 一、伺服电机参数二、气缸参数1. 输入IO映射&#xff08;1&#xff09;输入IO映射&#xff08;2&#xff09; 输入IO触摸屏标签显示映射 2. 输出IO映射&#xff08;1&#xff09;输出IO映射&#xff08;2&#xff09; …

基于单片机电动车电压电流监测系统

**单片机设计介绍&#xff0c;基于单片机电动车电压电流监测系统 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的电动车电压电流监测系统是一个集成了电子技术、单片机编程以及电压电流测量技术的系统。其主要目的是…

Open3D (C++) 从.txt文件中读取数据到矩阵

目录 一、算法概述二、代码实现三、结果展示四、测试数据本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、算法概述 在进行实验的时候有时需要借助不同的工具来实现一些比较复杂的操作,比如使用matlab中自带的拉…

lua学习笔记4(运算符的学习)

print("*****************************lua运算符的学习*******************************") print("*****************************基本运算符*******************************") a1145 b8848 print("加法运算"..ab) print("减法运算".…

Spark-Scala语言实战(14)

在之前的文章中&#xff0c;我们学习了如何在spark中使用键值对中的fullOuterJoin&#xff0c;zip&#xff0c;combineByKey三种方法。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点…

考研高数(平面图形的面积,旋转体的体积)

1.平面图形的面积 纠正&#xff1a;参数方程求面积 2.旋转体的体积&#xff08;做题时&#xff0c;若以x为自变量不好计算&#xff0c;可以求反函数&#xff0c;y为自变量进行计算&#xff09;

【STL学习】(3)vector容器

前言 本章主要内容为两个部分&#xff1a; vector是什么&#xff1f;vector常用接口的使用。 一、vector的介绍 vector是表示可变大小数组的容器就像数组一样&#xff0c;vector也采用的连续空间来存储元素。也意味着可以采用下标对vector的元素进行访问&#xff0c;和数组一样…

【二分查找】Leetcode 在排序数组中查找元素的第一个和最后一个位置

题目解析 34. 在排序数组中查找元素的第一个和最后一个位置 我们使用暴力方法进行算法演化&#xff0c;寻找一个数字的区间&#xff0c;我们可以顺序查找&#xff0c;记录最终结果 首先数组是有序的&#xff0c;所以使用二分法很好上手&#xff0c;但是我们就仅仅使用上一道题…

C++的并发世界(七)——互斥锁

0.死锁的由来 假设有两个线程T1和T2&#xff0c;它们需要对两个互斥量mtx1和mtx2进行访问。而且需要按照以下顺序获取互斥量的所有权&#xff1a; -T1先获取mte1的所有权,再获取mt2的所有权。 -T2先获取 mtx2的所有权。再铁取 mtx1的所有权。 如果两个线程同时执行&#xff0c…