最小生成树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;
}



 

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