Tarjan(五)vDCC缩点

news2024/11/25 10:53:13

Tarjan(五)

vDCC点双联通分量: 需要之前的前置知识,需要搞懂什么是割点。在tarjan(2)中有介绍到。

点双连通分量是指在一个无向图中,如果一个子图是点双连通的(即去掉该子图中的任意一个节点后,剩余的图仍然是连通的,不存在割点),则称这个子图为点双连通分量。换句话说,点双连通分量是图中的极大点双连通子图。

  1. 无割点:点双连通分量中不包含割点,即去掉该分量中的任意一个节点,剩余的图仍然是连通的。
  2. 路径多样性:在点双连通分量中,任意两点间至少存在两条“点不重复”的路径。这意味着,即使去掉了连接这两点的某一条路径上的所有节点(除了起点和终点),这两点之间仍然可以通过其他路径相连。
  3. 割点与点双连通分量的关系:任意割点都是至少两个点双连通分量的公共点。这是因为割点至少连接着图的两部分,而这两部分由于不能包含割点,所以分别属于不同的点双连通分量。

如上图:存在1、5两个割点,其中的联通分量有四个,用代码实现上述过程:

#include<iostream>
#include<vector>
#include<stack>
using namespace std;
const int N = 1e4 + 10, M = 2e5 + 10;

int n, m;
vector<int> e[N], ne[N]; // 对于点联通分量直接用领接表存边,没必要像边双联通分量一样把边按编号存起来,因为割点和割边的差异导致:割点允许往返走,例如可以从a->b,再从b->a,但是割边不行。
vector<int> vdcc[N];//记录点双联通分量
int dfn[N], low[N], tot, root; // root在割点中介绍过,判断某个节点是不是割点用的
int cut[N], idx,cnt; //cut[i]为1则表示i为割点
stack<int> stk; //方便记录点双联通分量
void tarjan(int x) {
    dfn[x] = low[x] = ++tot;
    cout << "dfn[" << x << "]=" << dfn[x] << '\n';
    if(!e[x].size()) { //孤立点
        cut[++idx] = x;
        cout << "eDCC:" << x << '\n';
        return; 
    }
    stk.push(x);
    int child = 0;
    for(int y : e[x]) {
        if(!dfn[y]) {
            tarjan(y);
            low[x] = min(low[x], low[y]);
            cout << "low[" << x << "]=" << low[x] << '\n';
            if(low[y] >= dfn[x]) {
                cout << "eDCC:";
                child++;
                if(x != root || child > 1)
                    cut[x] = 1;
                cnt++;
                while(1) { //和边双联通分量不同,vDCC在if(low[y] >= dfn[x])里面进行判断,不要写在if(x != root || child > 1)这个判断里面,因为这个是判断割点的,对于每个割点,至少属于两个vDCC,但是你只处理了一遍while循环,
                    int t = stk.top(); stk.pop();
                    cout << t << ' ';
                    vdcc[cnt].push_back(t); 
                    if(t == y) break; //这个条件已经不再是t == x,因为若x为割点,则x至少分别是两个点双联通分量的结点
                }
                vdcc[cnt].push_back(x); //所以x单独通过加入,而不是出栈x,因为可能是其他vdcc的结点。
                cout << x << '\n';
            }
        }else {
            low[x] = min(low[x], dfn[y]);
            cout << "*low[" << x << "]=" << low[x] << '\n';
        }
    }
}
int main() {
    cin >> n >> m;
    while(m--) {
        int a, b; cin >> a >> b;
        e[a].push_back(b);
        e[b].push_back(a);
    }
    for(root = 1; root <= n; root++) {
        if(!dfn[root]) tarjan(root);
    }

    return 0;
}

输出如上,可以看到输出中总共有4个联通块

那最终经过点双联通分量缩点后怎么建图,我们可以看到:

在这里插入图片描述

我们的vdcc点双联通分量共有4个,分别是上面的1,2,3,4.那5、6怎么来的?其实便是之前记录下来的割点cut[i],之前的1、5结点便是割点,只不过在新图后我们重新编号,从4后面编号。整个过程就好像原来的割点裂开分成多个,例如原来的1号结点,不仅出现在新图中的1联通块中,还出现在4联通块中,其实5结点也是原来的1号结点。

int num = cnt;
for(int i = 1; i <= n; i++) {
    if(cut[i]) gd[i] = ++num; 
}
for(int i = 1; i <= cnt; i++) {
    for(int j = 0; j < vdcc[i].size(); j++) {
        int x = vdcc[i][j];
        if(cut[x]) {
            ne[gd[x]].push_back(i);
            ne[i].push_back(gd[x]);
        }
    }
}
for(int i = 1; i <= cnt; i++) {
    cout << "vdcc: " << i << ':';
    for(int j = 0; j < ne[i].size(); j++) {
        cout << ne[i][j] << ' ';
    }
    cout << '\n';
}

如果还有疑惑,建议去看视频讲解:【D19 Tarjan vDCC 缩点】https://www.bilibili.com/video/BV18Z4y1v7tt?vd_source=4c9eb38d8205116069b961c84f64c958

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

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

相关文章

电商平台产品ID|CDN与预渲染|前端边缘计算

技术实现 都是通过ID拿到属性&#xff0c;进行预渲染html&#xff0c;通过 oss 分发出去 详情页这种基本都是通过 ssr 渲染出来&#xff0c;然后上缓存 CDN 分发到边缘节点来处理&#xff0c;具体逻辑可以参考 淘宝——EdgeRoutine边缘计算&#xff08;CDNServerless 边缘计算…

深度解析HAProxy:构建高可用负载均衡的终极指南

目录 haproxy配置文件组成 实验环境 haproxy安装 haproxy的配置文件说明 全局配置段global 多进程和多线程配置 代理配置段proxies server配置说明 实验相关配置 测试效果&#xff1a; haproxy的状态页 socat命令 socat命令的一些常用示例 HAProxy的调度算法 静…

Oracle事务是怎么练成的

什么是事务 事务是数据库管理系统执行过程的一个逻辑单位&#xff0c;由一系列有限的数据库操作序列构成&#xff0c;事务必须满足‌ACID属性。ACID理论是数据库中最重要的概念之一&#xff0c;分别代表原子性&#xff08;Atomicity&#xff09;、一致性&#xff08;Consisten…

人工智能GPU算力评估分析

GPU算力评估 一、 关于训练GPU的带宽 大模型训练算力需求&#xff1a;总算力(Tlops)6倍模型参数量训练数据token量&#xff0c;精准高效满足大规模训练需求。 需要把那么计算量和通信量的比例是多少&#xff1f; 3&#xff1a;指的是一次正向两次反向&#xff0c;反向是梯度…

程序员职场升级攻略:学AI技能,稳步迈向月薪破万之路

在人工智能高速发展的今天&#xff0c;AI技术已经成为职场人士提升收入的有力武器。许多人通过学习AI技能&#xff0c;成功跻身高收入行业&#xff0c;实现了月薪破万的目标。本文将揭秘高收入行业与城市&#xff0c;并提供一条清晰的学习路线&#xff0c;助你成为AI领域的一员…

ubuntu:更新阿里云apt源

前言 我用vmware也搭建了ubuntu服务器&#xff0c;并同样发现apt几乎完全用不了&#xff08;系统默认用的是清华源&#xff0c;可能较老了&#xff09; 更新阿里云apt源 1、去阿里云官网找系统对应的apt源配置 阿里云镜像&#xff1a;阿里巴巴开源镜像站-OPSX镜像站-阿里云开发…

Unity教程(九)角色攻击的改进

Unity开发2D类银河恶魔城游戏学习笔记 Unity教程&#xff08;零&#xff09;Unity和VS的使用相关内容 Unity教程&#xff08;一&#xff09;开始学习状态机 Unity教程&#xff08;二&#xff09;角色移动的实现 Unity教程&#xff08;三&#xff09;角色跳跃的实现 Unity教程&…

WindowsAPI 查阅笔记:进程间管道通信

进程间有名管道的通信&#xff1a; 1.1 重叠I/O&#xff08;Overlapped I/O&#xff09; 重叠I/O&#xff08;Overlapped I/O&#xff09;是Windows编程中的一种异步 I / O 处理方式&#xff0c;它允许程序在发出I/O请求后继续执行其他任务&#xff0c;而不必等待I/O操作完成…

萌啦定价工具,萌啦数据ozon定价工具

在电商行业日益竞争激烈的今天&#xff0c;精准定价成为了商家们获取市场竞争优势的关键一环。尤其是对于在Ozon平台上耕耘的卖家而言&#xff0c;无论是本土卖家还是跨境商家&#xff0c;如何快速、准确地制定出既符合市场需求又能保障利润的价格策略&#xff0c;成为了亟待解…

高防服务器的机制和原理

高防服务器是一种具备强大防御能力的服务器&#xff0c;旨在保护网站免受各种网络攻击&#xff0c;如DDoS&#xff08;分布式拒绝服务&#xff09;攻击、CC&#xff08;ChallengeCollapsar&#xff09;攻击等。今天小编将从流量过滤与清洗、负载均衡与反向代理、实时监控与报警…

圈内水刊“三巨头”之首实至名归?发文量飙升至9000+,硕博小白照样发1区TOP!

【SciencePub学术】昨天&#xff0c;小编给大家介绍了环境水刊“三巨头”之一的《Journal of Hazardous Materials》&#xff0c;本期&#xff0c;给大家带来的是位于环境水刊“三巨头”之首的《Science of the Total Environment》&#xff0c;属于JCR1区中科院1区TOP&#xf…

冷数据归档(历史库),成本与性能如何兼得?| OceanBase应用实践

随着数据量的迅猛增长&#xff0c;企业和组织在数据库管理方面遭遇的挑战愈发凸显。数据库性能逐渐下滑、存储成本节节攀升&#xff0c;以及数据运维复杂性的增加&#xff0c;这些挑战使得DBA和开发者在数据管理上面临更大的压力。 为了应对这些挑战&#xff0c;对数据生命周期…

vulnstack-5

环境搭建 靶场虚拟机共用两个&#xff0c;一个外网一个内网&#xff0c;用来练习红队相关内容和方向&#xff0c;主要包括常规信息收集、Web攻防、代码审计、漏洞利用、内网渗透以及域渗透等相关内容学习。 虚拟机密码 win7 sun\heart 123.com sun\Administrator dc123.com # …

华为软件测试笔试真题,赶快收藏

软件测试工程师笔试题目 一&#xff0e;填空 1、 系统测试使用&#xff08; C &#xff09;技术, 主要测试被测应用的高级互操作性需求, 而无需考虑被测试应用的内部结构。 A、 单元测试 B、 集成测试 C、 黑盒测试 D、白盒测试 2、单元测试主要的测试技术不包括&#xff08;…

【nvidia-smi】Failed to initialize NVML: Driver/library version mismatch

服务器更新后&#xff0c;输入nvidia-smi出现如下报错&#xff1a; 解决方法参考&#xff1a; 已解决【nvidia-smi】Failed to initialize NVML: Driver/library version mismatch解决方法-腾讯云开发者社区-腾讯云 (tencent.com) 输入命令查看nvidia驱动的版本号&#xff1a…

Linux软件包yum

目录 Linux软件包管理器 yum关于rzsz注意事项查看软件包如何安装软件卸载命令 Linux开发工具Linux编辑器-vim使用1. vim的基本概念2. vim的基本操作3. vim正常模式命令集4. vim末行模式命令集5. vim操作总结 小彩蛋 Linux软件包管理器 yum 软件包 在Linux下安装软件&#xff…

java基础学习笔记2(8.9)

String equals比较堆里值 字符串比较用str1.equals(str2)&#xff1b; 比较栈里的值 JDK7以后字符串常量池进入了堆里面。 在Java中&#xff0c;StringBuffer 和 StringBuilder 是用于创建可变字符串的类。它们提供了比 String 更高效的字符串操作&#xff0c;尤其是在需要…

ICM-20948芯片详解(13)

接前一篇文章&#xff1a;ICM-20948芯片详解&#xff08;12&#xff09; 六、寄存器详解 2. USER BANK 0寄存器详述 &#xff08;60&#xff09;FIFO_COUNTH 高5位&#xff0c;计数表示FIFO中写入的字节数。 &#xff08;61&#xff09;FIFO_COUNTL 低8位&#xff0c;计数表…

IMAX ENHANCED认证的护眼三色激光投影仪,选极米 RS 10 Pro把专业IMAX影院带回家

对于追求大屏体验的用户来说&#xff0c;智能投影仪有着电视机无法比拟的优势。因此&#xff0c;智能投影仪如今也逐步替代传统电视机&#xff0c;成为了许多家庭的必备家电之一。对于当代年轻人而言&#xff0c;无论是追剧、看电影还是打游戏&#xff0c;大屏幕都始终比传统电…

西部数据拒绝2.62亿美元巨额赔偿:硬盘专利侵权案将上诉

西部数据&#xff08;Western Digital&#xff0c;简称WD&#xff09;被加州的一个陪审团裁定需支付2.62亿美元的赔偿金&#xff0c;原因是该公司侵犯了德国科学家Dieter Suess拥有的硬盘驱动器&#xff08;HDD&#xff09;记录技术专利。Suess是维也纳大学功能性材料物理学教授…