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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Prim最小生成树算法

發(fā)布時(shí)間:2023/12/20 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Prim最小生成树算法 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?

????? 在一個(gè)具有幾個(gè)頂點(diǎn)的連通圖G中,如果存在子圖G'包含G中所有頂點(diǎn)和一部分邊,且不形成回路,則稱G'為圖G的生成樹,代價(jià)最小生成樹則稱為最小生成樹。??????????

????? 許多應(yīng)用問題都是一個(gè)求無向連通圖的最小生成樹問題。例如:要在n個(gè)城市之間鋪設(shè)光纜,主要目標(biāo)是要使這 n 個(gè)城市的任意兩個(gè)之間都可以通信,但鋪設(shè)光纜的費(fèi)用很高,且各個(gè)城市之間鋪設(shè)光纜的費(fèi)用不同;另一個(gè)目標(biāo)是要使鋪設(shè)光纜的總費(fèi)用最低。這就需要找到帶權(quán)的最小生成樹。

????? 性質(zhì)

  • 最小生成樹的邊數(shù)必然是頂點(diǎn)數(shù)減一,|E| = |V| - 1。
  • 最小生成樹不可以有循環(huán)。
  • 最小生成樹不必是唯一的。

Prim算法與Kruskal算法是尋找最小生成樹的經(jīng)典方法。

prim算法:

從單一頂點(diǎn)開始,普里姆算法按照以下步驟逐步擴(kuò)大樹中所含頂點(diǎn)的數(shù)目,直到遍及連通圖的所有頂點(diǎn)。

  • 輸入:一個(gè)加權(quán)連通圖,其中頂點(diǎn)集合為V,邊集合為E;
  • 初始化:Vnew = {x},其中x為集合V中的任一節(jié)點(diǎn)(起始點(diǎn)),Enew = {};
  • 重復(fù)下列操作,直到Vnew= V:
  • 在集合E中選取權(quán)值最小的邊(u, v),其中u為集合Vnew中的元素,而v則不是(如果存在有多條滿足前述條件即具有相同權(quán)值的邊,則可任意選取其中之一);
  • 將v加入集合Vnew中,將(u, v)加入集合Enew中;
  • 輸出:使用集合Vnew和Enew來描述所得到的最小生成樹。
  • ???? 為實(shí)現(xiàn)這個(gè)算法需要一個(gè)輔助數(shù)組closedge,來記錄Vnew到V-Vnew具有最小權(quán)值的邊。對(duì)于每個(gè)頂點(diǎn)vi∈V-Vnew,在輔助數(shù)組中存在一個(gè)分量closedge[i],表示vi到Vnew的最小代價(jià)邊,closedge包括兩個(gè)域, adjvex表示這條邊的頂點(diǎn),lowcost表示vi到adjvex的權(quán)值。當(dāng)選擇新的頂點(diǎn)到Vnew,選擇新的邊到Enew時(shí),要更新closedge

    ?無向加權(quán)圖:

    Graph #include <iostream> #include <vector> #include <queue> #define MAXW 1000//定義最大權(quán)值 using namespace std; template<class T> class Graph//無向加權(quán)圖 { public:Graph();~Graph();void Create();//生成加權(quán)圖void DFSTraverse(void (*fun)(T));//深度優(yōu)先遍歷void BFSTraverse(void (*fun)(T));//廣度優(yōu)先遍歷int LocateVex(T vex);int GetVexnum(){return vexnum;}int GetArcnum(){return arcnum;}int** GetAdjMatrix(){return adjMatrix;}T GetVex(int i){return vexs[i];} private:vector<T> vexs;//頂點(diǎn)數(shù)組int** adjMatrix;//鄰接矩陣int arcnum;//弧數(shù)int vexnum;//頂點(diǎn)數(shù)bool *visited;int FirstAdjVex(int v);//v的第一個(gè)鄰接點(diǎn)int NextAdjVex(int v,int w);//從w開始找v的下個(gè)鄰接點(diǎn)void DFS(int i,void (*fun)(T)); };template<class T> Graph<T>::Graph() {adjMatrix=NULL;arcnum=0;visited=NULL; }template<class T> Graph<T>::~Graph() {for (int i=0;i<vexnum;i++){delete [] adjMatrix[i];}delete adjMatrix;adjMatrix=0;delete [] visited; }template<class T> void Graph<T>::Create() {cout<<"輸入頂點(diǎn)數(shù),弧數(shù)(以空格隔開):";cin>>vexnum;cin>>arcnum;adjMatrix=new int*[vexnum];for(int i=0;i<vexnum;i++)adjMatrix[i]=new int[vexnum];for (int i=0;i<vexnum;i++){for(int j=0;j<vexnum;j++)adjMatrix[i][j]=MAXW;//初始化鄰接矩陣 }visited=new bool[vexnum];cout<<"輸入頂點(diǎn)列,以空格隔開:";for (int i=0;i<vexnum;i++){T temp;cin>>temp;vexs.push_back(temp);//輸入頂點(diǎn) }cout<<"輸入一條邊依附的頂點(diǎn)及權(quán)值(A B 1):"<<endl;for (int i=0;i<arcnum;i++){T v1,v2;int w;cin>>v1;cin>>v2;cin>>w;int x=LocateVex(v1);int y=LocateVex(v2);adjMatrix[x][y]=w;adjMatrix[y][x]=w;//設(shè)置權(quán)值 } }template<class T> int Graph<T>::LocateVex(T vex) {for(int i=0;i<vexnum;i++){if (vexs[i]==vex){return i;}}return -1; }template<class T> int Graph<T>::FirstAdjVex(int v) {for (int i=0;i<vexnum;i++){if(adjMatrix[v][i]!=MAXW)return i;}return -1; }template<class T> int Graph<T>::NextAdjVex(int v,int w) {for (int i=w+1;i<vexnum;i++){if(adjMatrix[v][i]!=MAXW)return i;}return -1; }template<class T> void Graph<T>::DFS(int i,void (*fun)(T))//從第i個(gè)頂點(diǎn)深度優(yōu)先遍歷 {visited[i]=true;fun(vexs[i]);for (int w=FirstAdjVex(i);w>=0;w=NextAdjVex(i,w)){if(!visited[w]) DFS(w,fun);}}template<class T> void Graph<T>::DFSTraverse(void (*fun)(T)) {for(int i=0;i<vexnum;i++)visited[i]=false;for (int i=0;i<vexnum;i++){if(!visited[i])DFS(i,fun);} }template<class T> void Graph<T>::BFSTraverse(void (*fun)(T)) {queue<int> Q;for(int i=0;i<vexnum;i++)visited[i]=false;visited[0]=true;fun(vexs[0]);Q.push(0);//頂點(diǎn)入隊(duì)while (!Q.empty()){//int v=Q.back();int v=Q.front();// 出隊(duì) Q.pop();for(int w=FirstAdjVex(v);w>=0;w=NextAdjVex(v,w)){if(!visited[w]){visited[w]=true;fun(vexs[w]);Q.push(w);//訪問后頂點(diǎn)入隊(duì) }}} }

    ?

    prim算法:

    template<class T> void MinSpanTree_PRIM(Graph<T> &G,T u) {//Prim算法,生成最小生成樹struct cell{T adjvex;//鄰接頂點(diǎn)int lowcost;//最小權(quán)值 };cell* closedge=new cell[G.GetVexnum()];//輔助數(shù)組int k=G.LocateVex(u);for (int i=0;i<G.GetVexnum();i++){if(i!=k){closedge[i].adjvex=u;closedge[i].lowcost=G.GetAdjMatrix()[k][i];}}closedge[k].lowcost=0;for (int i=1;i<G.GetVexnum();i++){int w=MAXW;for(int j=0;j<G.GetVexnum();j++){if(closedge[j].lowcost<w&&closedge[j].lowcost>0){w=closedge[j].lowcost;k=j;}}//輸出路徑cout<<endl;cout<<"找到路徑:"<<closedge[k].adjvex<<"----"<<G.GetVex(k)<<"權(quán)值:"<<w<<endl;closedge[k].lowcost=0;for(int j=0;j<G.GetVexnum();j++){//更新closedge[j]if (G.GetAdjMatrix()[k][j]<closedge[j].lowcost){closedge[j].adjvex=G.GetVex(k);closedge[j].lowcost=G.GetAdjMatrix()[k][j];}}}}

    main:

    void printfun(char ch) {cout<<ch<<" "; } int main() {Graph<char> G;G.Create();cout<<"深度優(yōu)先遍歷:";G.DFSTraverse(printfun);cout<<endl<<"廣度優(yōu)先遍歷:";G.BFSTraverse(printfun);MinSpanTree_PRIM(G,G.GetVex(0));return 1;}

    ?

    ?例子:

    原圖:

    運(yùn)行結(jié)果:

    ?

    轉(zhuǎn)載于:https://www.cnblogs.com/wonderKK/archive/2012/04/12/2444571.html

    總結(jié)

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

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。