最小生成树prim算法

来源:互联网 发布:数据库表结构设计 viso 编辑:程序博客网 时间:2024/06/05 05:44

一个连通图的生成树是一个极小的连通子图,它含有图中全部的顶点,但只有足以构成一棵树的n-1条边。所谓的最小成本,就是n个顶点,用n-1条边把一个连通图连接起来,并且使得权值的和最小。综合以上两个概念,我们可以得出:构造连通网的最小代价生成树,即最小生成树(Minimum Cost Spanning Tree)。找连通图的最小生成树,经典的有两种算法,普里姆算法和克鲁斯卡尔算法,这里介绍普里姆算法。在前面一讲Kruskal最小生成树 中已经介绍了最小生成树的算法。和Kruskal算法类似,Prim算法也是利用贪心算法来解决最小生成树。

最小生成树MST性质:假设N=(V,{E})是一个连通网,U是顶点集V的一个非空子集。若(u,v)是一条具有最小权值(代价)的边,

其中u∈U,v∈V-U,则必存在一颗包含边(u,v)的最小生成树。

prim算法过程为:

假设N=(V,{E})是连通图,TE是N上最小生成树中边的集合。算法从U={u0}(u0∈V),TE={}开始,

重复执行下述操作:

在所有u∈U,v∈V-U的边(u,v)∈E中找一条代价最小的边(u0,v0)并入集合TE,同时v0 并入U,直至U=V为止。

此时TE中必有n-1条边,则T=(V,{TE})为N的最小生成树。


代码如下:

package graph;
//求最小生成树的prim算法
import java.io.BufferedInputStream;
import java.util.Scanner;


public class Prim {
private int[][] map;
private int n;
private boolean[] flag;
private int sum;
static final int maxInt=Integer.MAX_VALUE;
public Prim(int[][] map,int n){
this.map=map;
this.n=n;
flag=new boolean[n];
}
public int prim(){
sum=0;
int mst[]=new int[n];
flag[0]=true;
for(int j=1;j<n;j++){
int min=maxInt;
int min_i=0;
for(int i=0;i<n;i++){
if(!flag[i]&&map[0][i]<min){
min=map[0][i];
min_i=i;
}
}
flag[min_i]=true;
System.out.println(""+mst[min_i]+"-"+min_i);
System.out.println("--"+map[0][min_i]);
for(int i=0;i<n;i++){
if(!flag[i]&&map[0][i]>map[min_i][i]){
map[0][i]=map[min_i][i];
mst[i]=min_i;
}
}
sum+=map[0][min_i];
}
return sum;
}
public static void main(String[] args) {
Scanner s=new Scanner(new BufferedInputStream(System.in));

int n=7;
int map[][]={{maxInt,28,maxInt,maxInt,maxInt,10,maxInt},
{28,maxInt,16,maxInt,maxInt,maxInt,14},
{maxInt,16,maxInt,12,maxInt,maxInt,maxInt},
{maxInt,maxInt,12,maxInt,22,maxInt,18},
{maxInt,maxInt,maxInt,22,maxInt,25,24},
{10,maxInt,maxInt,maxInt,25,maxInt,maxInt},
{maxInt,14,maxInt,18,24,maxInt,maxInt}};
System.out.println(new Prim(map,n).prim());
}
}


感谢博客:http://blog.csdn.net/niushuai666/article/details/6689295

0 0
原创粉丝点击