MST最短路徑 Prim演算法和Kruskal演算法

2021-10-04 22:20:19 字數 2184 閱讀 7102

最小生成樹問題有兩種經典的演算法,分別是prim和kruskal,他們的**有很多種,但要使複雜度更低,演算法的具體實現過程還是值得討論的:

這裡分別給出相對複雜度更低一點的**:

prim:

struct node

;node

(int a,

int b)

//建構函式

bool

operator

<

(const node& a)

const

//比較運算函式用以建優先佇列

}edge[

101]

;struct node2v[

101]

;

上述步驟已經順利寫出了兩組資料結構,第一組是儲存待會構造優先佇列的資料,第二組是儲存我們輸入的邊、點集,接下來是主函式:

int

main()

int u[

101]

,key[

101]

,p[101];

//u用來標記是否已經遍歷,key用來標記當前點的最短鄰接邊,p用來標記點的最短路徑所連線的端點

for(i =

1; i <= n; i++

) key[a]=0

;//從a開始選路線

priority_queue q;

q.push

(node

(a,0))

;while

(!q.

empty()

)}}for

(i =

1; i <= n; i++

)return0;

}

kruskal:

接下來我們再來**一下kruskal演算法,kruskal演算法的思想就是先把邊按照權值排序,遍歷的時候按照邊的權值大小來取邊,只要不形成迴路,這條邊就能使用:

先來構造資料結構:

struct node 

;node

(int a,

int b,

int c)

bool

operator

<

const

(node &a)

const

}edge[

101]

;int p[x]

, rank[x]

;//後述並查集需要用到

這樣我們的資料結構就已經構造完畢了,接下來是輸入的過程:

int

main()

用優先佇列直接將每一輪輸入壓入佇列中,在佇列中針對權值大小對每一條邊進行排序,接下來是取邊,取邊的時候我們需要保障不形成迴路,這裡就要用到並查集的思想,每乙個相連通的點都在同乙個union中,如果一條邊的兩個點不在乙個union中,那麼我們就可以取這條邊:

for

(i =

0; i <= n; i++

)int s =0;

while

(!q.

empty()

)}for(i =

0; i < s; i++

)return0;

}

到此我們的主函式就結束了,下面介紹一下並查集:

並查集就是集合,把一些特定相關的元素放到同乙個集合中,比如此處的相連通的點,就應該放在同乙個集合中,如果下次取邊的時候恰好邊的兩端點在同乙個集合中,那麼就說明如果把這條邊加上去圖就形成迴路了,豈不是一種很方便的操作?

補充:

find函式:

int

find

(int x)

link函式:

void

link

(int x,

int y)

else

if(rank[x]

> rank[y]

)else

if(rank[x]

< rank[y]

)}

最短路徑演算法 Dijkstra和Prim詳解

這幾次面試的確有好多次問到了最短路徑演算法,當時答得確實不好,對演算法理解的不是很透徹,下面簡單梳理一下。dijkstra演算法有點dp的意思,適用於單源最短路徑演算法且要求邊的權值非負,同時可以用於有向圖和無向圖。資料結構定義 思想 雙集合的說法可以查到很多,也解釋的很詳細,這裡說一下我的理解。記...

單源最短路徑 prim演算法

這一題是用二維陣列將點存入。scanf d d d x,y,z if a x y 0 else a x y z 至於那個判斷則是判重邊啦。先將每個點的權值賦最大 d陣列存點的值 const int inf 100000000 for i 1 i n i d i inf 現在將d的s位,也就是出發編號...

最短路徑演算法 最短路

在每年的校賽裡,所有進入決賽的同學都會獲得一件很漂亮的t shirt。但是每當我們的工作人員把上百件的衣服從商店運回到賽場的時候,卻是非常累的!所以現在他們想要尋找最短的從商店到賽場的路線,你可以幫助他們嗎?input 輸入包括多組資料。每組資料第一行是兩個整數n m n 100,m 10000 n...