问题描述
在 n 个城市之间铺设光缆,以保证这n个城市中的任意两个城市之间都可以通信。由于铺设光缆的价格很高,且各个城市之间的距离不同,这就使得在各个城市之间铺设光缆的价格不同。那么如何选择铺设线路的方案,才能使费用最低呢?
该问题就涉及到有权图的最小生成树问题。
基本概念
连通图:在无向图中,若任意两个顶点之间都有路径相通,则称该图为连通图。
强联通图:在有向图中,若任意两个顶点之间都有路径相通,则称该图为强连通图。
连通网:在连通图中,若图的边具有一定的意义,每一条边都对应着一个数,称为权;权代表着连接这两个顶点的代价,称这种连通图为连通网。
最小生成树:在连通网的所有生成树中,所有边的代价和最小的生成树,称为最小生成树。
普利姆算法——Prim算法
是加权连通图里生成最小生成树的一种算法。
算法流程
- 对于一个加权联通图,其顶点集合为V,边集合为E。从集合V中任选一个顶点作为初始顶点,将该顶点标为已处理。
- 已处理的所有顶点可以看成是一个集合U,计算所有与集合U中相邻的顶点的距离,选择距离最短的顶点,将其标记为已处理,并记录最短距离的边。
- 不断计算已处理的顶点集合U和未处理的顶点的距离,每次选出距离最短的顶点标为已处理,同时记录最短距离的边,直至所有顶点都处理完。
- 最终,所有记录的最短距离的边构成的树,即为最小生成树。
图解算法
性能分析
使用邻接矩阵来保存图的话,时间复杂度是 O ( n 2 ) O(n^2) O(n2)
克鲁斯卡算法——Kruskal算法
算法流程:
- 把图中的所有边按代价从小到大排序。
- 把图中的n个顶点看成是独立的n棵树组成的森林。
- 按照权值从大到小选择边,所选的边连接的两个顶点 u i u_i ui, v i v_i vi。 u i u_i ui, v i v_i vi应该属于两棵不同的树,则成为最小生成树的一条边,并将这两棵树合并为一棵树。
- 重复步骤3,直到所有的顶点都在一棵树内或者有n-1条边为止。
图解算法
性能分析
Kruskal算法需要先对所有边按照权值进行排序,这个操作的时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn),其中n为无向连通图边的数目。之后就是遍历排序后的所有边,并判断边所连接的两个顶点是否属于同一棵树,如果不是,就进行合并,所以总体的时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)。