最新强连通分量分解详解 超级详细,前端外包是如何转正华为的

结束

一次完整的面试流程就是这样啦,小编综合了腾讯的面试题做了一份前端面试题PDF文档,里面有面试题的详细解析,分享给小伙伴们,有没有需要的小伙伴们都去领取!

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

(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

#include <stdio.h>

#include

#include <string.h>

using namespace std;

vector data[10005];

vector rdata[10005];

vector flag;

int used[10005];

int kind[10005];

void add_edge(int i, int j)

{

data[i].push_back(j);

rdata[j].push_back(i);

刷面试题

刷题的重要性,不用多说。对于应届生或工作年限不长的人来说,刷面试题一方面能够尽可能地快速自己对某个技术点的理解,另一方面在面试时,有一定几率被问到相同或相似题,另外或多或少也能够为自己面试增加一些自信心,可见适当的刷题是很有必要的。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

  • 前端字节跳动真题解析

  • 【269页】前端大厂面试题宝典

最后平时要进行自我分析与评价,做好职业规划,不断摸索,提高自己的编程能力和抽象思维能力。大厂面试远没有我们想的那么困难,摆好心态,做好准备,你也可以的。

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值