普利姆最小生成樹演算法
普里姆演算法
(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...