這篇文章主要講解了普里姆算法(Prim算法),圖論中的一種算法,可在加權連通圖里搜索最小生成樹,需要的朋友可以參考下
本文介紹了最小生成樹的定義,Prim算法的實現步驟,通過簡單舉例實現了C語言編程。
1.什么是最小生成樹算法?
簡言之,就是給定一個具有n個頂點的加權的無相連通圖,用n-1條邊連接這n個頂點,并且使得連接之后的所有邊的權值之和最小。這就叫最小生成樹算法,最典型的兩種算法就是Kruskal算法和本文要講的Prim算法。
2.Prim算法的步驟是什么?
這就要涉及一些圖論的知識了。
a.假定圖的頂點集合為V,邊集合為E.
b.初始化點集合U={u}.//u為V中的任意選定的一點
c.從u的鄰接結點中選取一點v使這兩點之間的權重最小,然后將v加入集合U中.
d.從結點v出發,重復c步驟,直到V={}.
3.舉個例子來說明Prim算法的步驟:
一個簡單的加權拓撲圖如下所示
選取1為初始點,則按照上面所示的步驟訪問結點的順序依次次為:
則最終訪問結點的順序:1,3,4,2,5.
4.Prim算法的具體C語言編程實現:
- #include <stdio.h>
- #include <cstdlib>
- #include<memory.h>
- const int Max =0x7fffffff;
- const int N=50;
- int n;
- int g[N][N],dis[N],visited[N];
- int prim()
- {
- int i,j;
- int pos,min;
- int ans=0;
- memset(visited,0,sizeof(visited));
- visited[1]=1;pos=1;
- //assign a value to the dis[N] first
- for(i=2;i<=n;i++)
- dis[i]=g[pos][i];
- for(i=1;i<n;i++)
- {
- min=Max;
- for(j=1;j<=n;j++)
- {
- if(visited[j]==0&&min>dis[j])
- {
- min=dis[j];
- pos=j;
- }
- }
- printf("The node being traversed is :%d/n",pos);
- ans+=min;
- printf("The value of ans is %d/n",ans);
- //mark the node
- visited[pos]=1;
- //update the weight
- for(j=1;j<=n;j++)
- if(visited[j]==0&&dis[j]>g[pos][j])
- dis[j]=g[pos][j];
- }
- return ans;
- }
- int main()
- {
- int i=1,j=1;
- int ans=0;
- int w;
- printf("Please enter the number of the nodes:/n");
- scanf("%d",&n);
- for(i=1;i<=n;i++)
- for(j=1;j<=n;j++)
- {
- if(i==j)
- g[i][j]=0;
- else
- g[i][j]=Max;
- }
- printf("Please enter the number of the edges:/n");
- int edgenum;
- scanf("%d",&edgenum);
- int v1,v2;
- printf("Please enter the number and the corresponding weight:/n");
- for(i=1;i<=edgenum;i++)
- {
- scanf("%d%d%d",&v1,&v2,&w);
- g[v1][v2]=g[v2][v1]=w;
- }
- ans=prim();
- printf("The sum of the weight of the edges is:%d/n",ans);
- system("pause");
- return 0;
- }
5.程序運行后的結果截圖
以上就是本文的全部內容,希望對大家的學習有所幫助。
新聞熱點
疑難解答