探讨图的最短路径和最小生成树问题
本篇博客将重点阐述图的最短路径算法和图的最小生成树算法…
- 图的最短路径算法分为单源最短路和多源最短路,以及混搭的有无权图和有权图,具体的解决方法有Dijkstra算法,和Floyd算法;
- 最小生成树算法分为Prim算法和Kruskal算法,前者以收录点为导向,后者以收录边为导向。
写在前面
最短路径问题
1.无权图的单源最短路径
单源最短路径本质上可以转化为BFS求层数.
2.有权图的单源最短路径算法
Dijkstra算法的本质是,S集合为包含源点的已经收录的点集合,V为未收录的点集合,每次从V中取一个到S集合距离最小的点,然后遍历这个点的相邻点,用这个点到S集合的距离刷新相邻点到S集合的距离(向距离减少的方向变)。
3.多源最短路算法
- 方法1,直接用单源最短路使用N次,即对每个点都作为源点,然后使用N次单源最短路。
- 方法2,使用Floyd算法.
Floyd算法的本质是,取图中任意两点I和J,然后I到J的最短路有可能经过其他点,假设这个点为K,那么D[i][j]
表示i到j的最短路径,那么D[i][j]=min(D[i][j],D[i][k]+D[k][j])
,0<=k<n,用[0,n-1]范围内的点刷新D[i][j]
的距离.
最小生成树
- 定义:取图的|V|-1条边和全部的节点构成一个无回路的边权重之和最小的树。
- 性质:最小生成树存在<—>图连通
1.Prim算法-让小树长大
Prim算法与Dijkstra算法相似,区别是每次将相邻点的距离更新为min(dist[w],E[v,w]),换句话说,Prim算法的本质是将点集分为两个集合,即已收录集合S和未收录集合V,然后每次从未收录集合中取距离最小的点加入已收录集合中,本质上使用贪心算法,每次收录一个顶点时,决定收录哪一条两边呢,收录未在已收录集合中的点的最小边。
2. Kruskal算法-将森林合并成树
Kruskal算法与Prim算法不同,Prim算法以收录点为目的,而Kruskal算法以收录边为目的。即每次从边集合中取不构成回路的最小边。