無向最小生成樹(prim 與krusckal)總結

2021-07-23 02:21:52 字數 2068 閱讀 8663

之前學的時候一直感覺是兩個演算法沒什麼區別,今天總結一下:

大體思路:

prim演算法是做n次確定每乙個點,使其構成最小生成樹。

而相對比的是krusckal演算法是做n-1次,找到n-1條最短邊,以此來確定n個點。

假設給定n個點,以及m條邊,既然是無向的,且有可能使其連通,那麼邊數m必定是 n-1<= m <=n*(n-1)/2。

下面給出**和具體差別的思路想法:

1.prim演算法(確定點)

演算法的思想:

標記當前點(思路二的實現,思路乙隻是第一次空跑)

步驟: 取第乙個點,進行向外找到當前這乙個點可以到達的最短的邊,sum+=邊長,標記當前找到的點,防止以後再次訪問該點。

在當前已經拿到的兩個點,找下乙個使用最小的權值可以到達的另外乙個沒標記過的點。

在當前已經拿到的三個點,找。。。。。。。。。。。。。。。。。。。。。。。。。。

依次類推。到最後我們拿到了n個點,也就是n-1條邊,這就是最小的生成樹,即最小的權值和。

看了下網上各位的思路有兩種:

第一種是迴圈n次,

這個n分為了  

其中第一步是確定了當前使用的點,是空跑,當前權值並不發生改變。先給出第一種的**:

#include #include #define inf 99999999

using namespace std;

int n,m;

int mp[1005][1005];

int vis[1005];

int dis[1005];

void prim(int cur)

int index=cur;

int minn=inf;

for(int k=1;k<=n;k++)

prim(1);

return 0;

}

再給出第二種**:

是n-1次迴圈,因為在初始時已經確立了x點(比如vis[1])為起始點,進行多次尋找。

#include #include #define inf 99999999

using namespace std;

int n,m;

int mp[1005][1005];

int vis[1005];

int dis[1005];

void prim(int cur)

int index=cur;

int minn=inf;

vis[1]=1;//區別在這裡和下一行。

for(int k=1;k<=n-1;k++)//

prim(1);

return 0;

}

2.kruskal演算法

感覺還是很好理解的,看了別人的思路,可以自己手敲一遍,自己都可以按照學過的知識敲出來。

演算法思路:

n個點可以由n-1條邊連通,在不新增多餘邊的情況下,我們自然要找到這n-1條邊是哪些邊。

首先我們將這n個頂點看成n棵孤立的樹,接下來的操作是每一條邊將st ed兩個頂點連線。

當然如果這兩個頂點已經在同一棵樹上了,那麼我們這條邊加上後就一定會形成乙個圈,就浪費了這個權值,所以只有當兩個點不在一棵樹上的時候我們才進行連線。

那麼上述操作就是乙個並查集合並根節點的操作。

而這些邊的選取規則是從小到大依次選取,只要這條邊加入後不會形成圈(也就是邊的兩個點原來不在同一棵樹上)。

我們可以記錄一下我們已經加入了多少條邊,當邊數==n-1時候退出。

#include #include #include using namespace std;

int father[50005];

struct node

edge[50005];

int vis[50005];

int n,m;

int sum=0,temp=0;

int cmp(node x,node y)

sort(edge+1,edge+1+m,cmp);

kruskal();

return 0;

}

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