Kruskal算法求最小生成树(图是连通的)

Kruskal算法求图的最小生成树:

Kruskal算法本质上上是贪心算法,即每次从图中选取权重最小的安全边(安全边就是加入最小生成树中不会形成回路的边)加入最小生成树(刚开始为空集)中,然后把改边从原图中剔除,继续重复前面的步骤,直到从原图中剔除所有的边或者原图中所有顶点均加入到生成树中。
下面就是由一个图的邻接矩阵求其最小生成树的代码:
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package kruskal;
import java.util.*;
/**
 *
 * @author liuzhenzhao
 */
public class Kruskal {

    /**
     * @param args the command line arguments
     */
    class Edge implements Comparable<Edge>
    {
        int start;
        int end;
        int weight;

        public Edge(int start,int end,int weight)
        {
            this.start=start;
            this.end=end;
            this.weight=weight;
        }
        public Edge(Edge o)
        {
            this.start=o.start;
            this.end=o.end;
            this.weight=o.weight;
        }
        @Override
        public int compareTo(Edge o)
        {
            return this.weight-o.weight;
        }
    }
    ArrayList<Edge>MST_Kruskal(int [][]G)
    {
        ArrayList <Edge>list=new ArrayList<Edge>();
        ArrayList <Edge>temp=new ArrayList<Edge>();
        Set<Integer> set=new TreeSet<Integer>();
        if(G.length==0)
        {
            return list;
        }
        else
        {
           for(int i=0;i<G.length;i++)
           {
               for(int j=i+1;j<G[i].length;j++)
               {
                   if(G[i][j]>0)
                   {
                       temp.add(new Edge(i,j,G[i][j]));
                   }
               }
           }
           Collections.sort(temp);//对所有的边进行排序
           //下面依次访问权重最小的边
           for(int i=0;i<temp.size();i++)
           {
               Edge q=temp.get(i);
               if(set.contains(q.start)&&set.contains(q.end))//不添加重复的边
                   continue;
               //下面两个判断保证不会形成回路
               if(!set.contains(q.start))
                    set.add(q.start);
               if(!set.contains(q.end))
                    set.add(q.end);
               list.add(new Edge(q));//将安全的边加入list
;           }
           return list;
        }
    }
    public static void main(String[] args) 
    {
        Scanner in=new Scanner(System.in);
        int m=0,n=0;
        if(in.hasNextInt())
            m=in.nextInt();

        int [][]G=new int[m][m];
        for(int i=0;i<m;i++)
        {
            for(int j=i+1;j<m;j++)
            {
                if(in.hasNextInt())
                    G[i][j]=in.nextInt();
            }
        }
        Kruskal obj=new Kruskal();
        ArrayList<Edge> list=obj.MST_Kruskal(G);
        for(int i=0;i<list.size();i++)
        {
            System.out.println(list.get(i).start+"--"+list.get(i).end+"("+list.get(i).weight+")");
        }
    }

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值