最小生成樹kruskal算法 克魯斯卡爾算法

1、Kruskal算法描述

      Kruskal算法是基於貪心的思想得到的。首先我們把所有的邊按照權值先從小到大排列,接着按照順序選取每條邊,如果這條邊的兩個端點不屬於同一集合,那麼就將它們合併,直到所有的點都屬於同一個集合爲止。至於怎麼合併到一個集合,那麼這裏我們就可以用到一個工具——-並查集。換而言之,Kruskal算法就是基於並查集的貪心算法。

2、Kruskal算法實現過程

此算法主要依託於三個函數第一個則是cmp函數我們需要定義一個結構體來存一條路的端點和這條路的權值,而cmp函數實現的功能則是將每條路的權值從小到大排列,第二個和第三個因爲克魯斯卡爾算法是依託於並查集,所以需要遞歸尋找根節點的函數和將子節點壓縮的函數,在找到根節點不同的函數是需要將權值加起來,最後用num來計算出一共走了幾條路,當走了比點少一條路的時候代表找到了最小生成樹。

3、Kruskal算法代碼以及例題

 

You are assigned to design network connections between certain points in a wide area. You are given a set of points in the area, and a set of possible routes for the cables that may connect pairs of points. For each possible route between two points, you are given the length of the cable that is needed to connect the points over that route. Note that there may exist many possible routes between two given points. It is assumed that the given possible routes connect (directly or indirectly) each two points in the area. 
Your task is to design the network for the area, so that there is a connection (direct or indirect) between every two points (i.e., all the points are interconnected, but not necessarily by a direct cable), and that the total length of the used cable is minimal.

Input

The input file consists of a number of data sets. Each data set defines one required network. The first line of the set contains two integers: the first defines the number P of the given points, and the second the number R of given routes between the points. The following R lines define the given routes between the points, each giving three integer numbers: the first two numbers identify the points, and the third gives the length of the route. The numbers are separated with white spaces. A data set giving only one number P=0 denotes the end of the input. The data sets are separated with an empty line. 
The maximal number of points is 50. The maximal length of a given route is 100. The number of possible routes is unlimited. The nodes are identified with integers between 1 and P (inclusive). The routes between two points i and j may be given as i j or as j i. 

Output

For each data set, print one number on a separate line that gives the total length of the cable used for the entire designed network.

Sample Input

1 0

2 3
1 2 37
2 1 17
1 2 68

3 7
1 2 19
2 3 11
3 1 7
1 3 5
2 3 89
3 1 91
1 2 32

5 7
1 2 5
2 3 7
2 4 8
4 5 11
3 5 10
1 5 6
4 2 12

0

Sample Output

0
17
16
26
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<vector>
#include<math.h>
#include<map>
#include<queue>
#include<algorithm>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
struct node{
    int l,r,w;
}p[100005];
int m,n;
int num;
int sum;
int dis[100005];
int  cmp(node a,node b)
{
    return a.w<b.w;
}
int findd(int x)
{
    if(dis[x]==x)
        return x;
    return dis[x]=findd(dis[x]);
}
void covre(int a)
{
        int pp,qq;
        pp=findd(p[a].l);
        qq=findd(p[a].r);//保證了相同端點的權值不會相加
        if(pp!=qq)
         {
             dis[pp]=qq;
             sum+=p[a].w;
             num++;
         }
}
int main()
{
    int i,j;
    while(~scanf("%d %d",&m,&n))
    {
         num=0;sum=0;
        if(m==0)
            break;
        for(i=0;i<=m;i++)
            dis[i]=i;
        for(i=1;i<=n;i++)
           {
               int xx,yy,ww;
               scanf("%d %d %d",&xx,&yy,&ww);//將端點以及兩個端點間的權值輸入進結構體中
               p[i].l=xx;
               p[i].r=yy;
               p[i].w=ww;
           }
        sort(p+1,p+1+n,cmp);//將結構體數組按照從小到大的順序排序




        for(i=1;i<=n;i++)
        {
           covre(i);//進入函數尋找根節點以及合併
           if(num==m-1)//如果有m個點只需要找到m-1條路
            break;
        }
        printf("%d\n",sum);




    }
    return 0;
}



 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章