連通:如果頂點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 ...