日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Prim和Kruskal求最小生成树

發布時間:2025/3/15 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Prim和Kruskal求最小生成树 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Prim:

算法步驟:

1.任意結點開始(不妨設為v1)構造最小生成樹: 2.首先把這個結點(出發點)包括進生成樹里, 3.然后在那些其一個端點已在生成樹里、另一端點還未在生成樹里的所有邊中找出權最小的一條邊, 4.并把這條邊、包括不在生成樹的另一端點包括進生成樹, …。 5.依次類推,直至將所有結點都包括進生成樹為止

Pascal的渣渣代碼...

注:尋找最短的邊那一步可以用堆優化,但那樣還不如直接用Kruskal......

Reference:  http://www.nocow.cn/index.php/Prim%E7%AE%97%E6%B3%95

const vmax=1000; var w:array[1..vmax,1..vmax] of longint; i,j,k,v,e:longint; w:存儲鄰接矩陣 v:結點數 e:邊數procedure prim(v0:longint); var flag:array[1..vmax] of boolean; //flag:表示是否在樹中。true是, false否min,prevk,nextk:longint; beginfillchar(flag,sizeof(flag),0);flag[v0]:=true; //STEP2for i:=1 to v-1 do //最小生成樹中有v-1條邊 ,所以外層循環需要v-1次 //STEP5beginmin:=maxlongint;for k:=1 to v do if flag[k] then //尋找在最小生成樹中的點 k:當前在最小生成樹中的點for j:=1 to v do //STEP3//尋找與(最小生成樹中的點)的距離最短的點。// j:當前要找的不在最小生成樹中的點 if (not flag[j]) and (w[k,j]<min) and (w[k,j]<>0) then紫色代碼://判重:要找的點不能在最小生成樹中紅色代碼://k與j必須相連!beginmin:=w[k,j];nextk:=j; prevk:=k; //這條邊從在最小生成樹中的點出發 ,//擴展到當前不在最小生成樹中的點。//prevk:=k,prevk為起點,在最小生成樹中//nextk:=j,nextk為 終點,當前不在最小生成樹中end;if min<>maxlongint then //如果找到了nextk這樣的可以從當前最小生成樹中擴展出來//(可以進入最小生成樹)的點beginflag[nextk]:=true; //將nextk這樣的點加入最小生成樹 //STEP4writeln(prevk,‘ ’,nextk,‘ ’,min); //輸出這條邊end;end; end;begin fillchar(w,sizeof(w),0); readln(v,e); for k:=1 to e dobeginread(i,j);readln(w[i,j]);w[j,i]:=w[i,j];end;prim(1); //STEP1end. View Code

?

?

Kruskal:

算法步驟:

1、把圖中的邊按權值從小到大排序。 2、按從小到大的順序依次向樹中加邊。?????? 在添加每一條邊(u,v)時,如果u和V兩個點都已在樹中,一旦添加,就回構成回路,所以放棄該邊,在向后找下一條邊。 3、直到添加n-1條邊。

用并查集優化

#include <iostream> using namespace std;struct abc {int x,y,dat; };struct abc e[1000]; int f[1000]; int i,j,k,ans,n,m,tx,ty,tmp;int find(int x) {if (x!=f[x])f[x]=find(f[x]);return f[x]; }void iunion(int x,int y) {int fx=find(x);int fy=find(y);if (fx!=fy)f[fy]=fx; }void qsort(int l,int r) {int i,j,mid;struct abc t; i=l;j=r;mid=e[(l+r)/2].dat;do{while (e[i].dat<mid) i++;while (e[j].dat>mid) j--;if (!(i>j)){t=e[i];e[i]=e[j];e[j]=t;i++;j--;}}while (i<=j);if (l<j) qsort(l,j);if (i<r) qsort(i,r); }int main() {cin>>n>>m;for (i=1;i<=m;i++){cin>>tx>>ty>>tmp;e[i].x=tx;e[i].y=ty;e[i].dat=tmp;}for (i=1;i<=n;i++)f[i]=i;qsort(1,m);k=1;ans=0;for (i=1;i<=n-1;i++){while (find(e[k].x)==find(e[k].y)) k++;iunion(e[k].x,e[k].y);ans=ans+e[k].dat;cout<<e[k].x<<" "<<e[k].y<<" "<<e[k].dat<<endl;}cout<<ans<<endl; } View Code

?

轉載于:https://www.cnblogs.com/pdev/p/3869977.html

新人創作打卡挑戰賽發博客就能抽獎!定制產品紅包拿不停!

總結

以上是生活随笔為你收集整理的Prim和Kruskal求最小生成树的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。