最小生成樹 prim

2021-09-27 13:28:35 字數 1935 閱讀 9972

連通:如果頂點v和v』之間由路徑,則稱v和v』是連通的

連通圖:如果圖中任意兩個頂點都是連通的,則稱其為連通圖

連通子圖:子圖中的頂點為原圖的子集,且子圖是連通的

生成樹:乙個極小連通子圖,它包含圖中所有頂點,但是僅包含n-1條邊(n為頂點個數)

最小生成樹:在生成樹的基礎上,其各邊權值之和最小

mst性質:假設n是乙個連通網,u是頂點集v的乙個非空子集。若(u, v)是一條具有最小權值的邊,其中u屬於u,v屬於v-u,則必存在一棵包含邊(u,v)的最小生成樹。

最小生成樹要求:

先看要求三:權值之和最小,即每次選擇權值最小的邊即可。要求二:即保證圖中不存在環。要求一:每個頂點都要被選中。下面基於prim演算法介紹如何構建最小生成樹。

構造過程:

首先選擇乙個開始頂點(因為最小生成樹要求是包含所有頂點,因此選擇哪個開始頂點並不會影響最終結果)

將選中頂點放入集合u中,選擇集合u中的頂點到v-u中的最短路徑。

將選中的頂點(v-u內的頂點)放入集合u

重複步驟2、3,直至u = v

如上圖所示:首選頂點v1,將v1加入集合u。選擇v1到v-u內頂點距離最短的頂點v3,將v3加入集合u。選擇u內頂點到v-u內頂點距離最近的頂點,這裡需要注意的是:是從全域性的角度選擇,不是從單一頂點選擇最近的頂點。例如上圖,選擇v4結束,沒有可選的後,並沒有回溯到v6,選擇v6的鄰接點,而是選擇了v3->v2,因為v3->v2的距離為5,而v6->v5的距離為6。重複上述步驟,直至圖f所示(u = v)。

演算法步驟:

首先我們選擇鄰接矩陣儲存圖中各頂點間的關係。使用乙個標記陣列flag,標記加入u內的頂點。為了避免重複掃瞄,可以借助兩個陣列乙個記錄u內頂點到v-u內頂點的最短距離,另乙個記錄v-u內頂點到u內的最鄰接點。

初始化上述各陣列,儲存圖的二維矩陣每個元素初始化為無窮大。標記陣列全為false(表示u內無頂點)。記錄距離和鄰接點的陣列全為0。

給出圖中各頂點之間的關係,且給出開始頂點

根據開始頂點更新u到v-u內各頂點的距離(鄰接矩陣對應行與各鄰接點之間的關係),以及記錄鄰接點的陣列

找出記錄距離陣列中到u到v-u內頂點的最小值,對應頂點加入u,更新u到v-u內頂點的距離關係和鄰接點關係

重複步驟4,直至u = v

**示例:

#include

using

namespace std;

#define max_size 100

#define int 1e7

int graph[max_size]

[max_size]

;bool flag[max_size]

;int close[max_size]

;int low[max_size]

;void

init_array()

}void

init_graph

(int m)

}void

prim

(int n,

int s)

}for

(int i =

1; i <= n; i++)}

if(t == s)

return

; flag[t]

=true

;for

(int j =

1; j <= n; j++)}

}}intcalculate_weight

(int n)

intmain()

觀察**,每次查詢最小值要o(n)的時間,此外共需要執行n次,因此時間複雜度為o(n^2)。

最小生成樹 Prim

include stdio.h include stdlib.h include io.h include math.h include time.h define ok 1 define error 0 define true 1 define false 0 define maxedge 20 ...

最小生成樹 prim

演算法模型 由任意乙個頂點開始 將此頂點存入s集,剩餘頂點存入t集合 每次遍歷頂點,取一條能夠連線s與t最短邊e,直到所有頂點全部加入s include include define inf 1 30 int n,m,vis 110 low 110 int map 110 110 int init ...

最小生成樹 PRIM

這個是有關普利姆的演算法,從乙個點出發,找出與這個點相連的所有點的對應的權值最小的那個,然後再把這個點從集合中劃掉。模板如下 include include define inf 0xfffff define max 2005 using namespace std int map max max ...