【图论】【 割边】【C++算法】1192. 查找集群内的关键连接

2024-03-28 18:20

本文主要是介绍【图论】【 割边】【C++算法】1192. 查找集群内的关键连接,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

作者推荐

视频算法专题

本文涉及知识点

图论 割边
割边和割点类似,DFS(next)的返回值 如果小于等于time[cur] 则不是割边。
割点原理及封装好的割点类(预计2024年3月11号左右发布)

LeetCoce1192. 查找集群内的关键连接

力扣数据中心有 n 台服务器,分别按从 0 到 n-1 的方式进行了编号。它们之间以 服务器到服务器 的形式相互连接组成了一个内部集群,连接是无向的。用 connections 表示集群网络,connections[i] = [a, b] 表示服务器 a 和 b 之间形成连接。任何服务器都可以直接或者间接地通过网络到达任何其他服务器。
关键连接 是在该集群中的重要连接,假如我们将它移除,便会导致某些服务器无法访问其他服务器。
请你以任意顺序返回该集群内的所有 关键连接 。

示例 1:

输入:n = 4, connections = [[0,1],[1,2],[2,0],[1,3]]
输出:[[1,3]]
解释:[[3,1]] 也是正确的。
示例 2:

输入:n = 2, connections = [[0,1]]
输出:[[0,1]]

提示:
2 <= n <= 105
n - 1 <= connections.length <= 105
0 <= ai, bi <= n - 1
ai != bi
不存在重复的连接

代码

核心代码

class CNeiBo
{
public:	static vector<vector<int>> Two(int n, vector<vector<int>>& edges, bool bDirect, int iBase = 0) {vector<vector<int>>  vNeiBo(n);for (const auto& v : edges){vNeiBo[v[0] - iBase].emplace_back(v[1] - iBase);if (!bDirect){vNeiBo[v[1] - iBase].emplace_back(v[0] - iBase);}}return vNeiBo;}	static vector<vector<std::pair<int, int>>> Three(int n, vector<vector<int>>& edges, bool bDirect, int iBase = 0){vector<vector<std::pair<int, int>>> vNeiBo(n);for (const auto& v : edges){vNeiBo[v[0] - iBase].emplace_back(v[1] - iBase, v[2]);if (!bDirect){vNeiBo[v[1] - iBase].emplace_back(v[0] - iBase, v[2]);}}return vNeiBo;}static vector<vector<int>> Grid(int rCount, int cCount, std::function<bool(int, int)> funVilidCur, std::function<bool(int, int)> funVilidNext){vector<vector<int>> vNeiBo(rCount * cCount);auto Move = [&](int preR, int preC, int r, int c){if ((r < 0) || (r >= rCount)){return;}if ((c < 0) || (c >= cCount)){return;}if (funVilidCur(preR, preC) && funVilidNext(r, c)){vNeiBo[cCount * preR + preC].emplace_back(r * cCount + c);}};for (int r = 0; r < rCount; r++){for (int c = 0; c < cCount; c++){Move(r, c, r + 1, c);Move(r, c, r - 1, c);Move(r, c, r, c + 1);Move(r, c, r, c - 1);}}return vNeiBo;}
};//割点
class CCutPoint
{
public:CCutPoint(const vector<vector<int>>& vNeiB) : m_iSize(vNeiB.size()){m_vNodeToTime.assign(m_iSize, -1);m_vCutNewRegion.resize(m_iSize);		}void Init(const vector<vector<int>>& vNeiB){for (int i = 0; i < m_iSize; i++){if (-1 == m_vNodeToTime[i]){m_vRegionFirstTime.emplace_back(m_iTime);dfs(vNeiB, i, -1);}}}	const int m_iSize;const vector<int>& Time()const { return m_vNodeToTime; }//各节点的时间戳const vector<int>& RegionFirstTime()const { return m_vRegionFirstTime; }//各连通区域的最小时间戳vector<bool> CalCut()const { vector<bool> ret;for (int i = 0; i < m_iSize; i++){ret.emplace_back(m_vCutNewRegion[i].size());}return ret; }//const vector < vector<pair<int, int>>>& NewRegion()const { return m_vCutNewRegion; };
protected:int dfs(const vector<vector<int>>& vNeiB, const int cur, const int parent){int iMinTime = m_vNodeToTime[cur] = m_iTime++;OnBeginDFS(cur);int iRegionCount = (-1 != parent);//根连通区域数量for (const auto& next : vNeiB[cur]) {if (next == parent){continue;}if (-1 != m_vNodeToTime[next]) {iMinTime = min(iMinTime, m_vNodeToTime[next]);continue;}const int childMinTime = dfs(vNeiB, next, cur);iMinTime = min(iMinTime, childMinTime);if (childMinTime >= m_vNodeToTime[cur]) {iRegionCount++;m_vCutNewRegion[cur].emplace_back(m_vNodeToTime[next], m_iTime);}OnVisitNextEnd(childMinTime,cur, next);}if (iRegionCount < 2){m_vCutNewRegion[cur].clear();}return iMinTime;}virtual void OnVisitNextEnd(int childMinTime,int cur, int next) {};virtual void OnBeginDFS(int cur) {};vector<int> m_vNodeToTime;vector<int> m_vRegionFirstTime;vector < vector<pair<int, int>>> m_vCutNewRegion; //m_vCutNewRegion[c]如果存在[left,r) 表示割掉c后,时间戳[left,r)的节点会形成新区域int m_iTime = 0;
};class CCutEdge : public CCutPoint
{
public:using CCutPoint::CCutPoint;vector<vector<int>> m_vCutEdges;
protected:virtual void OnVisitNextEnd(int childMinTime, int cur, int next) override {if (childMinTime > m_vNodeToTime[cur]){m_vCutEdges.emplace_back(vector<int>{ cur,next });}}
};class Solution {
public:vector<vector<int>> criticalConnections(int n, vector<vector<int>>& connections) {auto neiBo = CNeiBo::Two(n, connections, false);CCutEdge cut(neiBo);cut.Init(neiBo);return cut.m_vCutEdges;}
};

测试用例


template<class T, class T2>
void Assert(const T& t1, const T2& t2)
{assert(t1 == t2);
}template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{if (v1.size() != v2.size()){assert(false);return;}for (int i = 0; i < v1.size(); i++){Assert(v1[i], v2[i]);}}int main()
{int n;vector<vector<int>> connections;{Solution sln;n = 2, connections = { {0,1} };auto res = sln.criticalConnections(n, connections);Assert({ { 0,1} }, res);}{Solution sln;n = 4, connections = { {0,1},{1,2},{2,0},{1,3} };auto res = sln.criticalConnections(n, connections);Assert({ { 1,3} }, res);}
}

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

这篇关于【图论】【 割边】【C++算法】1192. 查找集群内的关键连接的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/856362

相关文章

深入理解C++ 空类大小

《深入理解C++空类大小》本文主要介绍了C++空类大小,规定空类大小为1字节,主要是为了保证对象的唯一性和可区分性,满足数组元素地址连续的要求,下面就来了解一下... 目录1. 保证对象的唯一性和可区分性2. 满足数组元素地址连续的要求3. 与C++的对象模型和内存管理机制相适配查看类对象内存在C++中,规

Mysql 中的多表连接和连接类型详解

《Mysql中的多表连接和连接类型详解》这篇文章详细介绍了MySQL中的多表连接及其各种类型,包括内连接、左连接、右连接、全外连接、自连接和交叉连接,通过这些连接方式,可以将分散在不同表中的相关数据... 目录什么是多表连接?1. 内连接(INNER JOIN)2. 左连接(LEFT JOIN 或 LEFT

如何在一台服务器上使用docker运行kafka集群

《如何在一台服务器上使用docker运行kafka集群》文章详细介绍了如何在一台服务器上使用Docker运行Kafka集群,包括拉取镜像、创建网络、启动Kafka容器、检查运行状态、编写启动和关闭脚本... 目录1.拉取镜像2.创建集群之间通信的网络3.将zookeeper加入到网络中4.启动kafka集群

在 VSCode 中配置 C++ 开发环境的详细教程

《在VSCode中配置C++开发环境的详细教程》本文详细介绍了如何在VisualStudioCode(VSCode)中配置C++开发环境,包括安装必要的工具、配置编译器、设置调试环境等步骤,通... 目录如何在 VSCode 中配置 C++ 开发环境:详细教程1. 什么是 VSCode?2. 安装 VSCo

Spring Boot实现多数据源连接和切换的解决方案

《SpringBoot实现多数据源连接和切换的解决方案》文章介绍了在SpringBoot中实现多数据源连接和切换的几种方案,并详细描述了一个使用AbstractRoutingDataSource的实... 目录前言一、多数据源配置与切换方案二、实现步骤总结前言在 Spring Boot 中实现多数据源连接

QT实现TCP客户端自动连接

《QT实现TCP客户端自动连接》这篇文章主要为大家详细介绍了QT中一个TCP客户端自动连接的测试模型,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录版本 1:没有取消按钮 测试效果测试代码版本 2:有取消按钮测试效果测试代码版本 1:没有取消按钮 测试效果缺陷:无法手动停

C++11的函数包装器std::function使用示例

《C++11的函数包装器std::function使用示例》C++11引入的std::function是最常用的函数包装器,它可以存储任何可调用对象并提供统一的调用接口,以下是关于函数包装器的详细讲解... 目录一、std::function 的基本用法1. 基本语法二、如何使用 std::function

Nacos集群数据同步方式

《Nacos集群数据同步方式》文章主要介绍了Nacos集群中服务注册信息的同步机制,涉及到负责节点和非负责节点之间的数据同步过程,以及DistroProtocol协议在同步中的应用... 目录引言负责节点(发起同步)DistroProtocolDistroSyncChangeTask获取同步数据getDis

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

服务器集群同步时间手记

1.时间服务器配置(必须root用户) (1)检查ntp是否安装 [root@node1 桌面]# rpm -qa|grep ntpntp-4.2.6p5-10.el6.centos.x86_64fontpackages-filesystem-1.41-1.1.el6.noarchntpdate-4.2.6p5-10.el6.centos.x86_64 (2)修改ntp配置文件 [r