最小生成樹的構造
阿新 • • 發佈:2019-01-23
prim演算法(破圈法)
kruskal演算法(避圈法)
基本思想:
設G=(V,E)是網路,最小生成樹的初始狀態為只有VN個頂點而無邊的非聯通圖T,T中每個頂點自成一個連通圖。將集合E中的邊按權遞增順序排列,選擇 兩個頂點分別在不通風的連通圖且權最小的 邊加入圖T,則原來的兩個連通圖成為一個連通圖。以此類推,知道T中所有的頂點都在同一個連通圖中為止,該連通圖就是所求的最小生成樹。處理過程中加入邊時避免產生迴路,所以該演算法也稱避圈法。
儲存結構:
1.圖採用鄰接矩陣表示。
2.mst陣列型別為Edge,包括邊的起點、終點和權。演算法結束後,mst存放求出的最小生成樹的VN-1條邊。
3.用一個整型陣列status[0...VN-1]記錄各個頂點所屬的連通子圖,每個連通子圖用一個頂點的下表表示。
程式碼實現:
時間複雜度為O(n^3)。#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; }
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)