1. 程式人生 > >最小生成樹的構造

最小生成樹的構造

prim演算法(破圈法)

kruskal演算法(避圈法)

基本思想:

設G=(V,E)是網路,最小生成樹的初始狀態為只有VN個頂點而無邊的非聯通圖T,T中每個頂點自成一個連通圖。將集合E中的邊按權遞增順序排列,選擇 兩個頂點分別在不通風的連通圖且權最小的 邊加入圖T,則原來的兩個連通圖成為一個連通圖。以此類推,知道T中所有的頂點都在同一個連通圖中為止,該連通圖就是所求的最小生成樹。處理過程中加入邊時避免產生迴路,所以該演算法也稱避圈法。

儲存結構:

1.圖採用鄰接矩陣表示。

2.mst陣列型別為Edge,包括邊的起點、終點和權。演算法結束後,mst存放求出的最小生成樹的VN-1條邊。

3.用一個整型陣列status[0...VN-1]記錄各個頂點所屬的連通子圖,每個連通子圖用一個頂點的下表表示。

程式碼實現:

#include <iostream>
#define AdjType int
#define VN 6
#define MAX 1000
using namespace std;

struct GraphMatrix
{
    AdjType arc[VN][VN];
};
typedef struct{
    int start,stop;
    AdjType weight;
}Edge;
Edge mst[VN-1];

void kruskal(GraphMatrix* Pgraph,Edge *mst)
{
    int num=0,x,y,minWeight,status[VN];
    for(int i=0;i<VN;i++)
        status[i]=i;//每個頂點屬於自己代表的連通子圖
    while(num<VN-1){
        minWeight=MAX;
        for(int i=0;i<VN-1;i++)//找到最短邊
        for(int j=i+1;j<VN;j++){
            if(Pgraph->arc[i][j]<minWeight){
                x=i;y=j;minWeight=Pgraph->arc[i][j];
            }
        }
        if(minWeight==MAX){
            cout<<"No MST!\n";
            return ;
        }
        if(status[x]!=status[y]){//不屬於同一連通子圖
            mst[num].start=x;
            mst[num].stop=y;
            mst[num].weight=minWeight;
            num++;

            int j=status[y]; //原來statu[y]代表的連通子圖的結點,現都屬於status[x]代表的連通子圖
            for(int i=0;i<VN;i++)
            if(status[i]==j)
                status[i]=status[x];
        }
        Pgraph->arc[y][x]=Pgraph->arc[x][y]=MAX;//刪除已加入T的最短邊
    }
    cout<<"Edges(start_ver,stop_vex,weight) of MST:\n";
    for(int i=0;i<VN-1;i++)
        cout<<"("<<mst[i].start<<","<<mst[i].stop<<","<<mst[i].weight<<")\n";
}
int main()
{
    GraphMatrix *G=new struct GraphMatrix;
    for(int i=0;i<VN;i++)
        for(int j=0;j<VN;j++)
            cin>>G->arc[i][j];
    kruskal(G,mst);
    return 0;
}
時間複雜度為O(n^3)。

Input

0 10 1000 1000 19 21
10 0 5 6 1000 11
1000 5 0 6 1000 1000
1000 6 6 0 18 14
19 1000 1000 18 0 33
21 11 1000 14 33 0

Output

Edges(start_ver,stop_vex,weight) of MST:
(1,2,5)
(1,3,6)
(0,1,10)
(1,5,11)
(3,4,18)