6 最小生成樹

2021-10-05 18:08:12 字數 2525 閱讀 4522

生成樹是搜尋出來的,不同的搜尋演算法搜尋出來的生成樹也不同。

最小生成樹是建立在網(帶權圖)上的概念。

最小生成樹:尋找連線所有點(v

vv)的弧(v−1

v-1v−

1),權值和為最小。

樹有倆個特點:

可以應用在:

先解釋倆個概念:【切分】和【橫切邊】。

切分:將圖的點分成倆部分。

二分圖除了切分外,還要滿足乙個條件:

切分定理本身是關於橫切邊的定理。

橫切邊:倆端點不同(切分後不再同一部分)的弧。

所以,二分圖的弧都是橫切邊。

切分定理:有乙個切分,就有乙個橫切邊。且橫切邊中的最小邊一定屬於最小生成樹。

以上圖為例,反證法可證明。

不同點之間最小弧就是直線的那條。

思路:將所有弧排序,從最小的弧開始乙個乙個的選擇(貪心)。

kruskal的思想**於對切分定理的逆用。

每次選擇乙個最小弧,肯定是某個切分的橫切邊。

切分定理:先給定切分,再給定切分中所有的橫切邊最小的,就是最小生成樹的邊。

kruskal:無論怎樣切分,切分定理中最小的橫切邊,都是最小生成樹的邊,那直接選最小即可。

因為切分定理是正確的,所以kruskal演算法也是正確的。

kruskal複雜度:θ(e

∗log

e)\theta(e*loge)

θ(e∗loge)

typedef

struct edgee;

e e[max_edge]

;int

cmp(

const

void

* a,

const

void

* b )

void

kruskal

( adjmatrix *g )

qsort

( e, size,

sizeof

(e), cmp )

;makeset

(1024);

int k =

0, tot =0;

for(

int i=

0; im; i++)if

( k == g->n-1)

break;}

if( k != g->n-1)

printf

("\n無最小生成樹 %d, %d\n"

, k, tot)

;else

printf

("\n最小生成樹 = %d\n"

, tot)

;}

prim演算法也是對切分定理的應用。

prim複雜度:θ(n

2)\theta(n^)

θ(n2

)

void

prim

( adjmatrix *g )

visited[x]

=true

, cnt++

, sum +

= dis[x]

;// 將找到的最小邊加入,並標記為已訪問

// 遍歷當前頂點j所有邊,更新生成樹到每個非樹頂點距離

for( j =

0; j < g-

>n; j++)if

(!visited[j]

&& dis[j]

> g-

>matrix[x]

[j]&& g-

>matrix[x]

[j]>0)

dis[j]

= g-

>matrix[x]

[j];

}printf

("\n最小生成樹 = %d\n"

, sum)

;free

( visited )

; visited =

null

;free

( dis )

; dis =

null

;}

fredman-tarjan複雜度:θ(e

+log

v)\theta(e + lo**)

θ(e+lo

**)chazelle複雜度:θ(e

′)\theta(e')

θ(e′

),近似線性,如果從數學角度看,還是比線性高一點點。

最小生成樹 次小生成樹

一 最小生成樹 說到生成樹首先要解釋一下樹,樹是乙個聯通的無向無環圖,多棵樹的集合則被稱為森林。因此,樹具有許多性質 1.兩點之間的路徑是唯一的。2.邊數等於點數減一。3.連線任意兩點都會生成乙個環。對於乙個無向聯通圖g的子圖,如果它包含g的所有點,則它被稱為g的生成樹,而各邊權和最小的生成樹則被稱...

最小生成樹

package 圖 最小生成樹是用最少的邊吧把所有的節點連線起來。於是和圖的深度優先搜素差不多。class stack public void push int key public int pop 檢視棧頂的元素 public int peek public boolean isempty cla...

最小生成樹

define max vertex num 20 最大頂點數 typedef int adjmatrix max vertex num max vertex num 鄰接矩陣型別 typedef char vertextype typedef struct mgraph struct dnodecl...