專題 最小生成樹 一

2022-07-06 23:24:15 字數 2974 閱讀 9441

這個專題我們討論的問題是在無向圖中尋找一棵最小生成樹(minimum spanning tree)。這個問題對於有向圖的討論也是有意義的,只不過演算法更加複雜,這裡我們將只討論無向圖。最小生成樹存在當且僅當圖是連通的。此處我們不對概念做過多的介紹,直接介紹兩種主要的演算法:

1.kruskal演算法  2.prim演算法(這個演算法留到下一次吧,今晚偷懶,我要陪女朋友去了,哈哈哈!)

kruskal演算法:

第一種演算法本質是一種貪心策略,連續的按照最小權選擇邊,並且當且僅當所選的邊與已取的邊不產生圈時,將該邊加入到最小生成樹的集合裡。形式上,kruskal演算法實際上是在處理乙個森林--樹的集合。開始時存在|v|棵單節點樹(圖g的頂點),而演算法每一步新增一邊在將兩顆樹合併為一棵樹。當演算法終止時,所剩下的樹即為最小生成樹。如我們試圖用kruskal演算法尋找下面圖(graph)g的乙個最小生成樹,圓圈內的為頂點(vertex)的編號,連線代表圖得邊(edge),連線上的數字代表各個邊的權(weight)值。同時,我們將給出該演算法選取邊的步驟。

可能第一次會看不大明白,簡單來說,我們主要的貪心思路是每一步都選取權值最小的邊,且與已選擇的邊不生成圈。講到這,你可以回過頭看看上面的圖,是不是每次都是從最小的權值中選出邊,如果不生成圈,則在集合中加入該邊。

實現的方法有很多,最基本的資料結構要求就是並查集。我們順便在此處給出並查集的模板實現。

#ifndef _disjset_h

#define _disjset_h

const

int numsets = 1000

;typedef

int disjset[numsets + 1

];typedef

intsettype;

typedef

intelementtype;

void

initialize(disjset s);

void

setunion(disjset s, settype root1, settype root2);

settype find(elementtype x, disjset s);

void

initialize(disjset s)

/*按秩求並

*/void

setunion(disjset s, settype root1, settype root2)

}settype

find(elementtype x, disjset s)

#endif /* disjset */

這是目前最為高效的一種實現方式,雖然看似平平無奇(異常簡單,簡直腦癱),但是困難的是這個資料結構的平均時間的分析,是目前為止從未見過的形式(可能只是我)。所以數學不好的我選擇不給你們分析,m次setunion與find操作的執行時間為o(m logn)。

好的,有了基礎的資料結構,讓我們回到正題,下面我們給出kruskal演算法的偽**:

#ifndef _kruskal_h

#define _kruskal_h

void

kruskal(graph g)

}}#endif /*_kruskal_h*/

這裡的選取最小權值的邊是用優先佇列,當然我們也可以預先對邊排個序,依次選取,這個可以依據個人的喜好而定。

下面我們看一到簡單的模板題,以及給出ac**,既然是模板題,就不過多講解,初學者對著偽碼和原始碼就可以成功上手kruskal演算法。

/*按秩(高度)求並

*/void

setunion(disjset s, settype root1, settype root2)

}settype

find(elementtype x, disjset s)

#endif /* disjset */#include

#include

#include

using

namespace

std;

struct

edge;

typedef vector

graph;

intcmp(edge a, edge b)

void

kruskal(graph&g)

}printf(

"%d\n

", mstweight);

}int

main()

}kruskal(g);

}return0;

}雖然你們可能會覺得我得**好多不必要的typedef與一些其他的,但是這是我得習慣,看著舒服,哈哈哈~~

最小生成樹專題

首先來回顧一下最小生成樹的概念 在一給定的無向圖 g v,e 中,u,v 代表連線頂點 u 與頂點 v 的邊 即 而 w u,v 代表此邊 的權重,若存在 t 為 e 的子集 即 且為無迴圈圖,使得 的 w t 最小,則此 t 為 g 的最小生成樹。最小生成樹其實是最小權重生成樹的簡稱。簡單地說,就...

最小生成樹專題

一 prim演算法 poj1258 有n個農場,已知這n個農場都互相相通,有一定的距離,現在每個農場需要裝光纖,問怎麼安裝光纖能將所有農場都連通起來,並且要使光纖距離最小,輸出安裝光纖的總距離 資料 幾個點,矩陣表示各點中間的距離 40 4 9 21 4 0 8 17 9 8 0 16 21 17 ...

專題六 最小生成樹 Kuangbin

kuangbin專題 poj1251 jungle roads 最小生成樹 poj1278 networking 最小生成樹 poj2031 building a space station 最小生成樹 poj2421 constructing roads 最小生成樹 zoj1586 qs netw...