最小生成樹 兩種常見的寫法

2021-08-11 05:33:04 字數 2919 閱讀 8511

普利姆最小生成樹演算法

普里姆演算法

(prim演算法),圖論中的一種演算法,可在加權連通圖里搜尋

最小生成樹

。意即由此演算法搜尋到的邊子集所構成的樹中,不但包括了連通圖里的所有頂點(英語:vertex (graph theory)),且其所有邊的權值之和亦為最小。

1).輸入:乙個加權連通圖,其中頂點集合為v,邊集合為e;

2).初始化:vnew = ,其中x為集合v中的任一節點(起始點),enew = {},為空;

3).重複下列操作,直到vnew = v:

a.在集合e中選取權值最小的邊,其中u為集合vnew中的元素,而v不在vnew

集合當中,並且v∈v(如果存在有多條滿足前述條件即具有相同權值的邊,則可任意選取其中之一);

b.將v加入集合vnew中,將邊加入集合enew中;

4).輸出:使用集合vnew和enew來描述所得到的最小生成樹。

初始狀態:v是所有頂點的集合,即v=;u和t都是空! 

第1步:將頂點a加入到u中。 

此時,u=。 

第2步:將頂點b加入到u中。 

上一步操作之後,u=, v-u=;因此,邊(a,b)的權值最小。將頂點b新增到u中;此時,u=。 

第3步:將頂點f加入到u中。 

上一步操作之後,u=, v-u=;因此,邊(b,f)的權值最小。將頂點f新增到u中;此時,u=。 

第4步:將頂點e加入到u中。 

上一步操作之後,u=, v-u=;因此,邊(f,e)的權值最小。將頂點e新增到u中;此時,u=。 

第5步:將頂點d加入到u中。 

上一步操作之後,u=, v-u=;因此,邊(e,d)的權值最小。將頂點d新增到u中;此時,u=。 

第6步:將頂點c加入到u中。 

上一步操作之後,u=, v-u=;因此,邊(d,c)的權值最小。將頂點c新增到u中;此時,u=。 

第7步:將頂點g加入到u中。 

上一步操作之後,u=, v-u=;因此,邊(e,g)的權值最小。將頂點g新增到u中;此時,u=v。

此時,最小生成樹構造完成!它包括的頂點依次是:a b f e d c g。

1、直接就是進行上面的操作過程;

#include #include #define inf 1<<3

#define num 100

using namespace std;

int dot_num;//表示頂點數;

int dot_lines;//表示邊數;

int graph[num][num];//存放邊的權值(陣列法)

bool visted[num] =;

struct vnodeminside[num];//存放adjvex這個樹內和樹外連線頂點之間的最小的所有權值;

int min_xu()

//獲取最小的值;

return k;

}void minispantree(int v)

minside[v+1].lowcost = 0;

for(int i = 2;i<=dot_num;i++)

}}int main()

minispantree(0);

return 0;

}

克魯斯卡爾演算法

克魯斯卡爾演算法的時間複雜度為o(eloge)(e為網中邊的數目),因此它相對於普里姆演算法而言,適合於求邊稀疏的網的最小生成樹。

克魯斯卡爾演算法從另一途徑求網的最小生成樹。假設連通網n=(v,),則令最小生成樹的初始狀態為只有n個頂點而無邊的非連通圖t=(v,),圖中每個頂點自成乙個連通分量。在e中選擇代價最小的邊,若該邊依附的頂點落在t中不同的連通分量上,則將此邊加入到t中,否則捨去此邊而選擇下一條代價最小的邊。依次類推,直至t中所有頂點都在同一連通分量上為止。

例如圖為依照克魯斯卡爾演算法構造一棵最小生成樹的過程。代價分別為1,2,3,4的四條邊由於滿足上述條件,則先後被加入到t中,代價為5的兩條邊(1,4)和(3,4)被捨去。因為它們依附的兩頂點在同一連通分量上,它們若加入t中,則會使t中產生迴路,而下一條代價(=5)最小的邊(2,3)聯結兩個連通分量,則可加入t。因此,構造成一棵最小生成樹。

上述演算法至多對 e條邊各掃瞄一次,假若以「堆」來存放網中的邊,則每次選擇最小代價的邊僅需o(loge)的時間(第一次需o(e))。又生成樹t的每個連通分量可看成是乙個等價類,則構造t加入新的過程類似於求等價類的過程,由此可以以「樹與等價類」中介紹的 mfsettp型別來描述t,使構造t的過程僅需用o(eloge)的時間,由此,克魯斯卡爾演算法的時間複雜度為o(eloge)。

//克魯斯卡爾演算法求無向連通網的最小生成樹的程式

#include #include #define num 100

#define inf 1<<3

#define max_vertex_num 100

using namespace std;

int dot_num;//表示頂點數;

int dot_lines;//表示邊數;

int g[num][num];//存放邊的權值(陣列法)

bool visted[num] =;

struct vnodeminside[num];//存放adjvex這個樹內和樹外連線頂點之間的最小的所有權值;

void kruskal()

kruskal();

}

測試資料:

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

最小生成樹(兩種演算法)

ifndef min tree h define min tree h include include include include include data struct data struct.h include tool tool disjoint set.h 最小生成樹 假設圖中的頂點有n...

最小生成樹兩種解法

運用了貪心的演算法。是從某個頂點開始不斷新增邊的演算法。int cost max v max v 存邊權 int mincost max v 從集合x出發的邊到每個頂點的最小權值 int book max v int v intprim mincost 0 0 int res 0 while 1 i...

最小生成樹的兩種實現

kruskal演算法的實現 根據最一般的kruskal 演算法的實現原理,本人設計並實現的演算法如下 首先在此演算法中,選邊的過程中,要首先對存在邊按權值按非遞減的順序排列,以順序判斷並加入最小生成樹邊的集合。因此設計資料結構 typedef struct myedge,eptr 在此資料結構中,a...