【代码随想录day59】【C++复健】 47. 参加科学大会(dijkstra(堆优化版)精讲 );94. 城市间货物运输 I

前几天有些事情耽搁了,不过好在图论我完全不会,所以偷看代码思路也没有任何的心理负担,做起来反而相对独立思考更快一点点。

47. 参加科学大会(dijkstra(堆优化版)精讲 )

本来一开始以为这个堆优化版相对于朴素版就类似于kruskal算法之于prim算法,定睛一看才发现并非如此,区别还是有很多的。

因为是时隔好几天回来写代码,有一种恍若隔世的感觉,甚至有点忘了kruskal/prim以及dijkstra算法都是针对什么问题的,所以就问了一下GPT,没想到还是挺有收获的:

1. 计算目标的不同:

Prim 和 Kruskal:
  • 目标:构造一棵 最小生成树 (Minimum Spanning Tree, MST)
    • 目的在于找到一个无向图中连接所有节点的总权重最小的树。
    • 生成树不关注特定的起点或终点,而是全图的一种全局性质。
    • MST 确保所有节点都被连接且总权重最小,但并不保证某个节点到另一个节点的最短路径。
Dijkstra:
  • 目标:计算一个特定起点到图中所有其他节点的 最短路径
    • 主要用于单源最短路径问题。
    • 仅关注从起点到终点的最短权重和路径,而不会覆盖所有节点。

2. 输入图类型的不同:

特性 Prim/Kruskal Dijkstra
图类型 无向图 有向图或无向图均可
边权值特性 权值非负(负权值不影响) 权值必须非负

3. 使用的算法思想:

Prim:
  • 基于 贪心法 构造 MST。
  • 从某个节点出发,每次选择权值最小的边扩展树,直到包含所有节点。
  • 支持动态增加节点,并使用优先队列进行优化(时间复杂度可以为 O((n+m)log⁡n)O((n + m) \log n)O((n+m)logn))。
Kruskal:
  • 基于 贪心法并查集,构造 MST。
  • 将图中的所有边按权值排序,然后从最小权值开始加入树中,同时避免形成环。
  • 更适合处理稀疏图,时间复杂度为 O(mlog⁡m)O(m \log m)O(mlogm),其中 mmm 是边的数量。
Dijkstra:
  • 基于 贪心法 和优先队列。
  • 从起点出发,每次选择当前路径最短的节点,更新邻接节点的最短距离,直到所有节点的最短距离确定。
  • 时间复杂度为 O((n+m)log⁡n)O((n + m) \log n)O((n+m)logn)。

4. 结果的不同:

Prim 和 Kruskal:
  • 输出是一个包含 n−1n-1n−1 条边的 最小生成树
  • 生成树覆盖了所有节点,但并不提供任何节点对之间的最短路径信息。
  • 最小生成树 ≠ 最短路径树(MST 不适合直接用于单源最短路径问题)。
Dijkstra:
  • 输出是从起点到其他节点的最短路径。
  • 生成的树是以起点为根的 最短路径树
  • 最短路径树并不一定是最小生成树,因为两者优化目标不同。

简单来说,kruskal/prim的最终目的是要找一个最小生成树把所有节点都连起来,而dijkstra单纯只是想知道从a到b的最短路径是什么。

那次是很容易想到一个新的问题:最小生成树当中两个节点之间的距离是最短路径吗?

并不是。比如最小生成树当中有可能是a-d,c-d,那我从a到c就是a-d加上c-d的权值,那假设我有一个直接连接a-c的边且权值比a-d加上c-d的权值要小,那最小生成树里的这个权值就不是

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值