算法题-图论

图的表示

207.课程表
127.单词接龙

图的遍历

  1. DFS

    递归。。。
    200.岛屿数量
    239.矩阵中的最长递增路径

  2. BFS
    102.二叉树的层序遍历

    看到最短,首先想到的是BFS
    542.01矩阵
    207.课程表
    127.单词接龙

拓扑排序

对于一个有向无环图G进行拓扑排序,是将G中所有节点排成一个线性序列,该序列满足以下两个条件:① 每个节点有且仅出现一次 ② 若存在一条从节点A到节点B的路径,则在序列中A一定出现在B前面。

求一个有向无环图的拓扑排序步骤:

1.在图中找到一个没有前驱(入度为0)的节点,然后输出

2.从图中删除该节点和所有以它为起点的有向边 ( 使边到达的节点 v 的入度-1)

3.重复操作1和操作2,直到图为空 或 当前图不存在无前驱的顶点为止(图存在环)

210.课程表||

图的应用

最小生成树

最小生成树 (MST) 是 连接了图中所有节点且没有环,而且这些边的权值和最小

1584.连接所有点的最小费用
1631.最小体力消耗路径

  1. 普利姆Prim算法

    将顶点分为两类,一类是树顶点(加入树里的顶点),一类是非树顶点(不在树里面的)。首先任选一个顶点加入树里,然后遍历每个树顶点到非树顶点的距离,选最短距离的那个非树顶点加入,然后重复这个过程,直到每个顶点都在树里。


  2. 克鲁斯卡尔Kruskal算法

    首先按照边的权值进行从小到大开始排序,每次从剩余的边中选择权值较小的且边的两个顶点不在同一个集合(连在一起的顶点属于一个集合)内的边,加入到生成树,直到n-1条边为止。


  • 并查集

并查集(Union-Find),又称不相交集合(Disjoint Set Union, DSU),是一种用于处理不相交集合的合并与查询问题的数据结构。它支持两种主要操作:

查找(Find):确定一个元素属于哪个集合。

合并(Union):将两个不同的集合合并成一个集合。

最短路径
  1. 迪杰斯特拉Dijkstra算法
    单源最短路径,计算一个节点到其他所有节点的最短路径:
  • 将所有的顶点分为两部分,也就是已知最短路程的顶点集合P和未知最短路径的顶点集合Q。最开始,已知最短路径的顶点集合P中只有源点一个顶点。我们这里用一个vis[ i ]数组来记录哪些点在集合P中,源点对应的是1,表示存在。用dis[i]数组记录源点到自己的最短距离,初始化为一个很大值,源点对应的是0。
  • 在集合Q的所有顶点中选择一个离源点最近的顶点u(即dis[u]最小)加入到集合P。并考察所有以点u为起点的边,对每一条边进行松弛操作。例如存在一条从u到v的边,且v不在集合P中,那么可以通过将边u->v添加到尾部来拓展一条从s到v的路径,这条路径的长度是dis[u]+e[u][v]。如果这个值比目前已知的dis[v]的值要小,我们可以用新值来替代当前dis[v]中的值。
  • 重复2过程,直到所有顶点添加到P中


    743.网络延迟时间
  1. 弗洛伊德Floyd算法

    多源最短路径

  2. 贝尔曼福特Bellman-Ford算法

  • 用于求解单源、有负权边的最短路问题
  • "求出从起点到终点不超过m条边构成的最短路径"
  • 其优于Dijkstra的方面是边的权值可以为负数、实现简单,缺点是时间复杂度过高。时间复杂度是O(nm)

787. K 站中转内最便宜的航班

3.1 与迪杰斯特拉算法的区别:

  • 迪杰斯特拉算法是借助贪心思想,每次选取一个未处理的最近的结点,去对与他相连接的边进行松弛操作;贝尔曼福特算法是直接对所有边进行N-1遍松弛操作
  • 迪杰斯特拉算法要求边的权值不能是负数;贝尔曼福特算法边的权值可以为负数,并可检测负权回路

3.2 算法步骤

​​- 初始化​​:将起点到所有其他顶点的距离初始化为无穷大(INF),起点到自身的距离初始化为 0。

​​- 松弛操作​​:对图中的每一条边进行 V-1 次松弛操作(V 是图中顶点的数量)。松弛操作的定义是:对于边 (u, v),如果 distance[u] + weight(u, v) < distance[v],则更新 distance[v] = distance[u] + weight(u, v)。

​​- 检测负权环​​:再进行一次松弛操作,如果还能找到更短的路径,则说明图中存在负权环。

3.3 为什么对每一条边进行v-1次松弛操作,每个可到达的节点都可以得到最短路径?

在一个无负权环的图中,每次松弛操作相当于"尝试"通过当前边 (u, v) 缩短 v 的最短路径,最坏情况下,最多经过 v-1 次松弛,所有节点的最短路径一定会被找到。

3.4 为什么可以检测负权图?

如果图中没有负权环,经过 V-1 次松弛后,所有最短路径都已经确定,不会再被更新。

如果还能继续松弛,说明存在一个环,使得路径可以无限缩短(因为负权环的总权重为负,绕环越多,路径越短)。

3.5 怎么求出不超过m条边的最短路径

每次松弛操作相当于"尝试"通过当前边 (u, v) 缩短 v 的最短路径,假设a->b->c->d,三条边由最后往前依次给出,那么遍历三次,所有的顶点的最短路径才找到,要"求出从起点到终点不超过m条边构成的最短路径",最多经过m次对所有边的松弛操作就可以找到 到终点不超过m条边构成的最短路径,再多一次 可能变成 超过m条的最短路径了。

3.6 优化SPFA算法

Bellman-Ford 的朴素实现是 O(VE),但实际中很多边不会被松弛。​​SPFA(Shortest Path Faster Algorithm)​​ 是 Bellman-Ford 的优化版本,使用队列来只松弛那些可能被更新的顶点,平均时间复杂度可以接近 O(E),但在最坏情况下仍然是 O(VE)。

相关推荐
清羽_ls20 分钟前
leetcode-位运算
前端·算法·leetcode·位运算
猫猫头有亿点炸32 分钟前
C语言中小写字母转大写字母
c语言·开发语言·算法
天天扭码1 小时前
一杯珍珠奶茶的时间吃透一道高频面试算法题——搜索二位矩阵Ⅱ
前端·算法·面试
pljnb1 小时前
聚类算法(K-means、DBSCAN)
算法·kmeans·聚类
2301_807611491 小时前
46. 全排列
c++·算法·leetcode·深度优先·回溯
天天扭码1 小时前
一杯蜜桃四季春的时间吃透一道高频面试算法题——旋转图像
前端·算法·面试
爱的叹息2 小时前
【java实现+4种变体完整例子】排序算法中【堆排序】的详细解析,包含基础实现、常见变体的完整代码示例,以及各变体的对比表格
java·算法·排序算法
天天扭码2 小时前
一桶泡面的时间解决高频面试算法题——螺旋矩阵
前端·算法·面试
长安思2 小时前
在C#串口通信中,一发一收的场景,如何处理不同功能码的帧数据比较合理,代码结构好
java·jvm·算法
CoovallyAIHub2 小时前
MobileNetV2:面向移动端的高效神经网络架构革新——突破轻量化模型的设计边界
人工智能·算法·计算机视觉