克鲁斯卡尔(Kruskal)算法求最小生成树
1、基本思想:設無向連通網為G=(V, E),令G的最小生成樹為T=(U, TE),其初態為U=V,TE={ },然后,按照邊的權值由小到大的順序,考察G的邊集E中的各條邊。若被考察的邊的兩個頂點屬于T的兩個不同的連通分量,則將此邊作為最小生成樹的邊加入到T中,同時把兩個連通分量連接為一個連通分量;若被考察邊的兩個頂點屬于同一個連通分量,則舍去此邊,以免造成回路,如此下去,當T中的連通分量個數為1時,此連通分量便為G的一棵最小生成樹。
2、示例:
3、代碼實現如下:
#include "stdio.h" #include "stdlib.h" struct edge {int m;int n;int d; }a[5010]; int cmp(const void *a,const void *b) //按升序排列 {return ((struct edge *)a)->d>((struct edge *)b)->d; } int main(void) {int i,n,t,num,min,k,g,x[100];printf("請輸入頂點的個數:");scanf("%d",&n);t=n*(n-1)/2;for(i=1;i<=n;i++)x[i]=i;printf("請輸入每條邊的起始端點、權值:/n");for(i=0;i<t;i++)scanf("%d %d %d",&a[i].m,&a[i].n,&a[i].d); //輸入每條邊的權值qsort(a,t,sizeof(a[0]),cmp);min=num=0;for(i=0;i<t && num<n-1;i++){for(k=a[i].m;x[k]!=k;k=x[k]) //判斷線段的起始點所在的集合x[k]=x[x[k]];for(g=a[i].n;x[g]!=g;g=x[g]) //判斷線段的終點所在的集合x[g]=x[x[g]];if(k!=g) //如果線段的兩個端點所在的集合不一樣{x[g]=k;min+=a[i].d;num++;printf("最小生成樹中加入邊:%d %d/n",a[i].m,a[i].n);}}printf("最小生成樹的權值為:%d/n",min);system("pause");return 0; }
?
總結
以上是生活随笔為你收集整理的克鲁斯卡尔(Kruskal)算法求最小生成树的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一道关于宏的面试题及解答
- 下一篇: 普里姆(Prim)求最小生成树