前提:
生成樹是建立在無向圖的基礎上的,所以下面的討論都是在無向圖上進行的。
直觀的乙個應用就是:有n個村莊,現在要在這些村莊之間修一些路,其中村莊i和村莊j之間的距離是dij,現在要修最短的路使得所有村莊連線起來。
最小生成樹( mit )的經典解決方法有2種:prim演算法和kruskal演算法。
1.prim演算法
演算法思想:設圖g頂點集合為u,首先任意選擇圖g中的一點作為起始點a,將該點加入集合v,再從集合u-v中找到另一點b使得點b到v中任意一點的權值最小,此時將b點也加入集合v;以此類推,現在的集合v=,再從集合u-v中找到另一點c使得點c到v中任意一點的權值最小,此時將c點加入集合v,直至所有頂點全部被加入v,此時就構建出了一顆mst。因為有n個頂點,所以該mst就有n-1條邊,每一次向集合v中加入乙個點,就意味著找到一條mst的邊。
演算法需要3個陣列來實現:
arr[i][j]:存放點到點之間的權值,初始值為最大值,若 是該兩點之間有邊則改變權值
a[i]:表示以i為終點的邊的最小權值,當a[i]=0說明以i為終點的邊的最小權值=0,也就是表示i點加入了mst
s[i]:表示對應a[i]的起點,即說明邊< s[i],i>是mst的一條邊,當s[i]=0表示起點i加入mst
例子:
任取一點作為起始點,假設選 點 v1.
則 a[2]=6, a[3]=0, a[4]=5, a[5]=無窮,a[6]=無窮
s[2]=3, s[3]=0, s[4]=1, s[5]=1, a[6]=1 ,
可以看出 a[3] 的值最小,所以 點 v3 加入mst,於是更新陣列:
a[2]=5, a[3]=0, a[4]=5,a[5]=6,a[6]=4
s[2]=3, s[3]=0, s[4]=1, s[5]=3,a[6]=3 ,
a[6]的值最小,所以 點 v6加入 mst,更新陣列:
a[2]=5, a[3]=0, a[4]=2,a[5]=6,a[6]=0
s[2]=3, s[3]=0, s[4]=6, s[5]=3,a[6]=0 ,
a[4]的值最小,所以點 v4 加入 mst,更新陣列:
a[2]=5, a[3]=0, a[4]=0,a[5]=6,a[6]=0
s[2]=3, s[3]=0, s[4]=0, s[5]=3,a[6]=0 ,
a[2]陣列的值最小,所以點 v2 加入 mst,更新陣列:
a[2]=0, a[3]=0, a[4]=0,a[5]=3,a[6]=0
s[2]=0, s[3]=0, s[4]=0, s[5]=2,a[6]=0 ,
a[5]陣列的值最小,所以點 v5 加入 mst,更新陣列:
a[2]=0, a[3]=0, a[4]=0,a[5]=0,a[6]=0
s[2]=0, s[3]=0, s[4]=0, s[5]=0,a[6]=0 ,
所有的點都加入到了mst中,結束。
//最小生成樹演算法,輸出點路徑以及權值
#include
using
namespace
std;
const
int maxn=1000;
const
int maxnum=100000;
int arr[maxn][maxn];
int a[maxn];
int s[maxn];
int n,m;
void prims(int begin)
s[begin]=0;
for(i=1;i<=n;i++)
cout
<
>begin;
prims(begin);
return
0;}
測試資料:610
1261
3114
5235
2533
4535
6364
4625663
結果:
2.kruskal演算法(使用並查集實現)
例子:
以圖為例,kruskal演算法的步驟:
取得權值最小的邊 v1 到 v3
在不構成乙個圈的情況下,取得權值次小的邊:v4 到 v6
實現**:
#include
#include
using
namespace
std;
const
int maxn=1000;
struct node
void kruskal()
}if(ans1)
sort(arr,arr+m);
kruskal();
return
0;}
測試資料:
6 10
1 2 6
1 3 1
1 4 5
2 3 5
2 5 3
3 4 5
3 5 6
3 6 4
4 6 2
5 6 6
實驗結果:
15
最小生成樹(prim演算法)
最小生成樹是資料結構中圖的一種重要應用,它的要求是從乙個帶權無向完全圖中選擇n 1條邊並使這個圖仍然連通 也即得到了一棵生成樹 同時還要考慮使樹的權最小。prim演算法要點 設圖g v,e 其生成樹的頂點集合為u。把v0放入u。在所有u u,v v u的邊 u,v e中找一條最小權值的邊,加入生成樹...
最小生成樹 Prim演算法
prim 演算法 以領接矩陣儲存 圖g bool b i 表示頂點i是否被訪問,初始化時候memset b,false,sizeof b b 0 value,表示從第0個節點開始。用value i 表示節點i到最小生成樹a中定點的最小距離。例如value 1 a 0 1 int sum記錄權值和 i...
最小生成樹 prim 演算法
一 演算法描述 假設存在連通帶權圖g v,e 其中最小生成樹為t,首先從圖中隨意選擇一點s屬於v作為起始點,並將其標記後加入集合u 中。然後演算法重複執行操作為在所有v屬於u,u屬於v u的邊 v0,u0 屬於e中找一條代價最小的邊並加入集合t,同時將u0併入u,直到u v為止。這是,t中必有n 1...