最小生成樹 prim

2022-08-20 13:42:10 字數 1218 閱讀 5852

1.演算法思想:

圖採用鄰接矩陣儲存,貪心找到目前情況下能連上的權值最小的邊的另一端點,加入之,直到所有的頂點加入完畢。

2.演算法實現步驟:

設圖g =(v,e),其生成樹的頂點集合為u。

(1)把v0放入u。

(2)在所有u∈u,v∈v-u的邊(u,v)∈e中找一條最小權值的邊,加入生成樹。

(3)把②找到的邊的v加入u集合。如果u集合已有n個元素,則結束,否則繼續執行②。

最後得到最小生成樹u=,其中te為最小生成樹的邊集。

其演算法的時間複雜度為o(n^2)。

3.演算法的關鍵與優化:

我們很容易就可以發現prim演算法的關鍵:每次如何從生成樹t到t外的所有邊中,找出一條最小邊。例如,在第k次前,生成樹t中已有k個頂點和(k-1)條邊,此時,t到t外得所有邊數為k*(n-k),當然,包括沒有邊的兩頂點,我們記權值為「無窮大」的邊在內,從如此多的邊中查詢最短邊,時間複雜度為o(k(n-k)),顯然無法滿足我們的期望。

我們來看o(n-k)的方法:假定在進行第k次前已經保留著從t中到t外的每乙個頂點(共n-k個)的各一條最短邊,在進行第k次時,首先從這(n-k)條最短邊中,找出一條最最短邊(它就是從t到t外的最短邊),假設為(vi,vj),此步需要進行(n-k)次比較;然後把邊(vi,vj)和頂點vj併入t中的邊集te和頂點集u中,此時,t外只有n-(k+1)個頂點,對於其中的每個頂點vt,若(vj,vt)邊上的權值小於原來儲存的從t中到vt的最短邊的權值,則用(v,vt)修改之,否則,保持原最小邊不變。這樣就把第k次後t中到t外的每乙個頂點vt的各一條最短邊都保留下來了,為第(k+1)次最好了準備。這樣prim的總時間複雜度為o(n^2)。

進一步優化,每次要尋找集合內外連線的最小值,可以用堆或優先佇列最小值時間複雜度為o(longn),總時間複雜度為n(nlongn).

**:

void

prim()

vis[next]=true; //

選中頂點j併入集合內

for (j=1;j<=n;j++)//

更新集合內集合外最短距離陣列cost;

if ((!vis[j]&& cost[j]cost[j]=map [next][j]

}return

;

}

最小生成樹 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 ...