图论经典问题(拓扑排序、最短路径、最小生成树)

拓扑排序

G是有n个顶点的有向图,G的拓扑排序是对G的每条边(v_i,v_j)来说G的顶点的顺序v_1,...,v_n,这种情况下i<j。也就是说,拓扑排序是一种排序,使得G的有向路径以增加的顺序遍历顶点。需要注意的是一个有向图可能不止有一个拓扑排序。

在有向图中以顶点表示活动,有向边表示活动之间的先后关系,这样的图称为AOV网拓扑排序就是将各活动排一个先后次序

命题:G有一个拓扑排序当且仅当它是非循环的

做法:1.从有向图中选一个没有前驱的顶点,并且输出 2.删除该顶点以及以它为起点的边。重复这两个步骤。直到找不到没有前驱的点

应用: - 判断是否有环(无环图的所有点都能进行拓扑排序) - 课程安排问题

代码:

最短路径

定义G为加权图,路径的长度(或权重)是P的边的权重的总和。图中顶点u到顶点v之间的距离表示为d(u,v),是从u到v之间长度最短的路径,如果这样的路径存在的话

Dijkstra算法

我们对V中的每个顶点v定义一个标签D[v],存储目前为止从sv找到的最好的路径的长度。首先,对每个v≠s,D[s]=0并且D[v]=∞,然后定义C集合,初始状态下是空集合。在算法的每次迭代总,选择不在C中有最短的D[u]标签的顶点u,然后把u放进C。一旦新顶点u被放进C中,接下来更新每个邻近u并且在C之外的顶点v的标签D[v]

最小生成树

问题定义:对于一个无向有权的图G,我们希望找到一棵树,它包含G中的所有顶点,并最小化权重总和

这样的包括连通图G的每个顶点的树被称为生成树,计算一棵有最小权重总和的生成树T的问题称为最小生成树(MST)问题

命题:G是一个有权重的连通的图,令V_1V_2是两个不相交的非空集合的G的顶点的一部分。令e是那些一个端点在V_1另一个端点在V_2的有最小权重的G的边。这就是一棵最小生成树,e是它的一条边。

如果G的权重是不同的,那么最小生成树是唯一的

Prim-Jarnik算法

贪心准则——加入后仍形成树,且耗费最小

算法过程:1.从单一顶点的树T开始 2.不断加入耗费最小的边(u,v),使T∪(u,v)仍为树

Kruskal算法

找最短的边,连接了AB,判断AB是否被已选的边连在一起,如果是就不选这条边

实现的方法——并查集

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容