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+")");
        }
    }

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章