贪心算法-4.6.1最小生成树之Prim算法(切分定理)

来源:互联网 发布:简明python教程豆瓣 编辑:程序博客网 时间:2024/06/07 12:23
public class test4_6_1 {    static float[] lowcast;    static int[] closest;    static boolean[] s;    public static void prim(int n,float[][] c){        lowcast = new float[n];  //到顶点[i]最小的权值        closest = new int[n];    //到顶点[i]最小权值的点        s = new boolean[n];      //顶点[i]是否被加入        //1.初始化        s[0] = true;  //率先把第一个点加入        for(int i=1;i<n;i++){            lowcast[i] = c[0][i];  //初始化,设到第[i]个点最小的权值是现有第一个点到此点的权值            closest[i] = 0;    //初始化,设第一个加进去的点是到第[i]个点最小权值的点            s[i] = false;         }        for(int i=1;i<n;i++){  //添加n-1个点            //2.找最小-j            float min = Float.MAX_VALUE;   //找最小的权值            int j=1;                        //找最小的点的序号,初始值为1的原因是初始化循环已经设置为1            for(int k=1;k<n;k++){                if((min>lowcast[k])&&(!s[k])){ //若有还没加进去的点,且此点对应边最小权值小于min                    min = lowcast[k];                    j = k;                }            }            s[j] = true;  //将找找最小的点加进来            //3.调整            for(int k=1;k<n;k++){                if((c[j][k]<lowcast[k])&&(!s[k])){  //若新加进去的点到其他没加进去的点的权值小于没加进去点本身                    lowcast[k] = c[j][k];                    closest[k] = j;                }            }        }    }    public static void main(String[] args) {        int n = 4;  //点的个数        float[][] c = {{ 0, 4, 9, 21},  //边权                       { 4, 0, 8, 17},                       { 9, 8, 0, 16},                       {21,17,16,  0}};        prim(n,c);        int sum=0;        for(int i=1;i<n;i++){            sum += lowcast[i];                  System.out.print("<"+closest[i]+","+i+">"+" ");            System.out.println(lowcast[i]);        }        System.out.println("最小生成树权和最小为:"+sum);    }}

运行结果如下:

<0,1> 4.0<1,2> 8.0<2,3> 16.0最小生成树权和最小为:28

时间复杂度:O(n^2),适用于边多的情况。