基本概念
生成树
给定一个带权的无向连通图,能够连通该图的全部顶点且不产生回路的子图即为该图的生成树;
极小连通子图
一个连通图的生成树是一个极小连通子图,它含有图中全部N个顶点且只有足以构成一棵树的N-1条边;
最小生成树 (简称MST)
- 给定一个带权的无向连通图,如何选取一棵生成树,使得树上所有边的权总和最小,这棵生成树就叫做最小生成树;
- 给定N个顶点的无向连通图,其最小生成树一定有N-1条边;
- 最小生成树中含有N个顶点;
- 最小生成树中的N-1条边都在给定的无向连通图中;
问题引出
首先看这样一个场景:
- 现在有7个村庄(A,B,C,D,E,F,G),需要修路将这7个村庄连通起来;
- 问如何修路保证使得各个村庄连通起来,并且修路的总长度最短;
思路:需要保证修路的条数尽可能少且每条路的长度尽可能短,即
- N个顶点(村庄)最少需要N-1条边(路)进行连通;
- 每次修新路时都选择 {能连接 [已经连通起来的几个村庄] 的公路} 中最短的那条将新的村庄连通进来,比如说当已经把 <A–(2)–G> 连通起来时,我们选择的下一条边应该是 <A–(5)–B> <A–(7)–C> <G–(3)–B> <G–(4)–E> <G–(6)–F>中最短的那条,即 <G–(3)–B>,将B与A–G连通;
prim算法介绍
- 普利姆(Prim)算法求最小生成树,就是在给定含有N个顶点的带权无向连通图中,找出包含N个顶点且只有N-1条边的连通子图,也即常说的极小连通子图,并保证该子图的权值和最小
- 普利姆算法思路:
1)设G=(V,E)是给定的无向带权图,T=(U,D)是最小生成树,V,U是顶点集合,E,D是边的集合
2)若从G中一个顶点v开始构造最小生成树的,则先从V集合中取出v放入集合U中;
3)寻找集合U中顶点ui与集合V-U中顶点vj之间权值最小且不形成回路的边,将顶点vi加入到U集合中,并将边(ui,vj)加入到集合D中;
4)重复步骤3),直到所有N个顶点都加入到U中,此时D中恰有N-1条边;
代码实现
import java.util.Arrays;
public class PrimAlgorithm {
public static void main(String[] args) {
char[] data = new char[] {
'A', 'B', 'C', 'D', 'E', 'F', 'G' };
int verNum = data.length;
int[][] weight = new int[][] {
// 1024表示无边
{
1024, 5, 7, 1024, 1024, 1024, 2 },
{
5, 1024, 1024