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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

Prim算法 求出 最小生成树

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

MST(Minimum Spanning Tree,最小生成樹)問題有兩種通用的解法,Prim算法就是其中之一,它是從點的方面考慮構建一顆MST,大致思想是:設圖G頂點集合為U,首先任意選擇圖G中的一點作為起始點a,將該點加入集合V,再從集合U-V中找到另一點b使得點b到V中任意一點的權值最小,此時將b點也加入集合V;以此類推,現在的集合V={a,b},再從集合U-V中找到另一點c使得點c到V中任意一點的權值最小,此時將c點加入集合V,直至所有頂點全部被加入V,此時就構建出了一顆MST。因為有N個頂點,所以該MST就有N-1條邊,每一次向集合V中加入一個點,就意味著找到一條MST的邊。

?

用圖示和代碼說明:

初始狀態:

設置2個數據結構:

lowcost[i]:表示以i為終點的邊的最小權值,當lowcost[i]=0說明以i為終點的邊的最小權值=0,也就是表示i點加入了MST

mst[i]:表示對應lowcost[i]的起點,即說明邊<mst[i],i>是MST的一條邊,當mst[i]=0表示起點i加入MST

?

我們假設V1是起始點,進行初始化(*代表無限大,即無通路):

?

lowcost[2]=6,lowcost[3]=1,lowcost[4]=5,lowcost[5]=*,lowcost[6]=*

mst[2]=1,mst[3]=1,mst[4]=1,mst[5]=1,mst[6]=1,(所有點默認起點是V1)

?

明顯看出,以V3為終點的邊的權值最小=1,所以邊<mst[3],3>=1加入MST

此時,因為點V3的加入,需要更新lowcost數組和mst數組:

?

lowcost[2]=5,lowcost[3]=0,lowcost[4]=5,lowcost[5]=6,lowcost[6]=4

mst[2]=3,mst[3]=0,mst[4]=1,mst[5]=3,mst[6]=3


明顯看出,以V6為終點的邊的權值最小=4,所以邊<mst[6],6>=4加入MST

?

此時,因為點V6的加入,需要更新lowcost數組和mst數組:

?

lowcost[2]=5,lowcost[3]=0,lowcost[4]=2,lowcost[5]=6,lowcost[6]=0

mst[2]=3,mst[3]=0,mst[4]=6,mst[5]=3,mst[6]=0

?


明顯看出,以V4為終點的邊的權值最小=2,所以邊<mst[4],4>=4加入MST

?

此時,因為點V4的加入,需要更新lowcost數組和mst數組:

?

lowcost[2]=5,lowcost[3]=0,lowcost[4]=0,lowcost[5]=6,lowcost[6]=0

mst[2]=3,mst[3]=0,mst[4]=0,mst[5]=3,mst[6]=0


明顯看出,以V2為終點的邊的權值最小=5,所以邊<mst[2],2>=5加入MST

?

此時,因為點V2的加入,需要更新lowcost數組和mst數組:

?

lowcost[2]=0,lowcost[3]=0,lowcost[4]=0,lowcost[5]=3,lowcost[6]=0

mst[2]=0,mst[3]=0,mst[4]=0,mst[5]=2,mst[6]=0


很明顯,以V5為終點的邊的權值最小=3,所以邊<mst[5],5>=3加入MST

?

lowcost[2]=0,lowcost[3]=0,lowcost[4]=0,lowcost[5]=0,lowcost[6]=0

mst[2]=0,mst[3]=0,mst[4]=0,mst[5]=0,mst[6]=0


至此,MST構建成功,如圖所示:

根據上面的過程,可以容易的寫出具體實現代碼如下(cpp):

[cpp]?view plaincopy print?
  • #include<iostream>??
  • #include<fstream>??
  • using??namespace?std;??
  • ??
  • #define?MAX?100??
  • #define?MAXCOST?0x7fffffff??
  • ??
  • int?graph[MAX][MAX];??
  • ??
  • int?prim(int?graph[][MAX],?int?n)??
  • {??
  • ????int?lowcost[MAX];??
  • ????int?mst[MAX];??
  • ????int?i,?j,?min,?minid,?sum?=?0;??
  • ????for?(i?=?2;?i?<=?n;?i++)??
  • ????{??
  • ????????lowcost[i]?=?graph[1][i];??
  • ????????mst[i]?=?1;??
  • ????}??
  • ????mst[1]?=?0;??
  • ????for?(i?=?2;?i?<=?n;?i++)??
  • ????{??
  • ????????min?=?MAXCOST;??
  • ????????minid?=?0;??
  • ????????for?(j?=?2;?j?<=?n;?j++)??
  • ????????{??
  • ????????????if?(lowcost[j]?<?min?&&?lowcost[j]?!=?0)??
  • ????????????{??
  • ????????????????min?=?lowcost[j];??
  • ????????????????minid?=?j;??
  • ????????????}??
  • ????????}??
  • ????????cout?<<?"V"?<<?mst[minid]?<<?"-V"?<<?minid?<<?"="?<<?min?<<?endl;??
  • ????????sum?+=?min;??
  • ????????lowcost[minid]?=?0;??
  • ????????for?(j?=?2;?j?<=?n;?j++)??
  • ????????{??
  • ????????????if?(graph[minid][j]?<?lowcost[j])??
  • ????????????{??
  • ????????????????lowcost[j]?=?graph[minid][j];??
  • ????????????????mst[j]?=?minid;??
  • ????????????}??
  • ????????}??
  • ????}??
  • ????return?sum;??
  • }??
  • ??
  • int?main()??
  • {??
  • ????int?i,?j,?k,?m,?n;??
  • ????int?x,?y,?cost;??
  • ????ifstream?in("input.txt");??
  • ????in?>>?m?>>?n;//m=頂點的個數,n=邊的個數??
  • ????//初始化圖G??
  • ????for?(i?=?1;?i?<=?m;?i++)??
  • ????{??
  • ????????for?(j?=?1;?j?<=?m;?j++)??
  • ????????{??
  • ????????????graph[i][j]?=?MAXCOST;??
  • ????????}??
  • ????}??
  • ????//構建圖G??
  • ????for?(k?=?1;?k?<=?n;?k++)??
  • ????{??
  • ????????in?>>?i?>>?j?>>?cost;??
  • ????????graph[i][j]?=?cost;??
  • ????????graph[j][i]?=?cost;??
  • ????}??
  • ????//求解最小生成樹??
  • ????cost?=?prim(graph,?m);??
  • ????//輸出最小權值和??
  • ????cout?<<?"最小權值和="?<<?cost?<<?endl;??
  • ????system("pause");??
  • ????return?0;??
  • }??

  • Input:

    ?

    ?

    [plain]?view plaincopy print?
  • 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??

  • Output:

    ?

    ?

    [plain]?view plaincopy print?
  • V1-V3=1??
  • V3-V6=4??
  • V6-V4=2??
  • V3-V2=5??
  • V2-V5=3??
  • 最小權值和=15??
  • 請按任意鍵繼續.?.?.??
  • ?

    ?

    java實現: /** prim最小生成樹** 參數說明:* start -- 從圖中的第start個元素開始,生成最小樹*/ public void prim(int start) {int num = mVexs.length; // 頂點個數int index=0; // prim最小樹的索引,即prims數組的索引char[] prims = new char[num]; // prim最小樹的結果數組int[] weights = new int[num]; // 頂點間邊的權值// prim最小生成樹中第一個數是"圖中第start個頂點",因為是從start開始的。prims[index++] = mVexs[start];// 初始化"頂點的權值數組",// 將每個頂點的權值初始化為"第start個頂點"到"該頂點"的權值。for (int i = 0; i < num; i++ )weights[i] = mMatrix[start][i];// 將第start個頂點的權值初始化為0。// 可以理解為"第start個頂點到它自身的距離為0"。weights[start] = 0;for (int i = 0; i < num; i++) {// 由于從start開始的,因此不需要再對第start個頂點進行處理。if(start == i)continue;int j = 0;int k = 0;int min = INF;// 在未被加入到最小生成樹的頂點中,找出權值最小的頂點。while (j < num) {// 若weights[j]=0,意味著"第j個節點已經被排序過"(或者說已經加入了最小生成樹中)。if (weights[j] != 0 && weights[j] < min) {min = weights[j];k = j;}j++;}// 經過上面的處理后,在未被加入到最小生成樹的頂點中,權值最小的頂點是第k個頂點。// 將第k個頂點加入到最小生成樹的結果數組中prims[index++] = mVexs[k];// 將"第k個頂點的權值"標記為0,意味著第k個頂點已經排序過了(或者說已經加入了最小樹結果中)。weights[k] = 0;// 當第k個頂點被加入到最小生成樹的結果數組中之后,更新其它頂點的權值。for (j = 0 ; j < num; j++) {// 當第j個節點沒有被處理,并且需要更新時才被更新。if (weights[j] != 0 && mMatrix[k][j] < weights[j])weights[j] = mMatrix[k][j];}}// 計算最小生成樹的權值int sum = 0;for (int i = 1; i < index; i++) {int min = INF;// 獲取prims[i]在mMatrix中的位置int n = getPosition(prims[i]);// 在vexs[0...i]中,找出到j的權值最小的頂點。for (int j = 0; j < i; j++) {int m = getPosition(prims[j]);if (mMatrix[m][n]<min)min = mMatrix[m][n];}sum += min;}// 打印最小生成樹System.out.printf("PRIM(%c)=%d: ", mVexs[start], sum);for (int i = 0; i < index; i++)System.out.printf("%c ", prims[i]);System.out.printf("\n"); }

    ?

    轉載于:https://www.cnblogs.com/sz-zzm/p/5553059.html

    總結

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

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