kruskal算法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了kruskal算法相关的知识,希望对你有一定的参考价值。

参考技术A

kruskal算法指克鲁斯卡尔算法。

克鲁斯卡尔算法是求连通网的最小生成树的另一种方法。与普里姆算法不同,它的时间复杂度为O(eloge)(e为网中的边数),所以,适合于求边稀疏的网的最小生成树 。

克鲁斯卡尔(Kruskal)算法从另一途径求网的最小生成树。其基本思想是:假设连通网G=(V,E),令最小生成树的初始状态为只有n个顶点而无边的非连通图T=(V,),概述图中每个顶点自成一个连通分量。

在E中选择代价最小的边,若该边依附的顶点分别在T中不同的连通分量上,则将此边加入到T中;否则,舍去此边而选择下一条代价最小的边。依此类推,直至T中所有顶点构成一个连通分量为止。

克鲁斯卡尔算法的时间复杂度主要由排序方法决定,而克鲁斯卡尔算法的排序方法只与网中边的条数有关,而与网中顶点的个数无关,当使用时间复杂度为O(elog2e)的排序方法时,克鲁斯卡尔算法的时间复杂度即为O(log2e),因此当网的顶点个数较多、而边的条数较少时,使用克鲁斯卡尔算法构造最小生成树效果较好。

(最小生成树)Kruskal算法

            (最小生成树)Kruskal算法

  算法要点:Kruskal算法的最难点在于怎样判断加入边(x, y)后是否形成了环.

  问题可化简为:判断边(x, y)的两个顶点在图(实际是森林)mst中是否已连通。如果已经连通,加入边将形成环;

否则,不形成环。

  Kruskal算法中, 要用到并查集的合并与查找。

  完整代码如下:(具体见代码注释)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int fa[1000010];
 4 int n, m;
 5 int sum = 0;
 6 struct node
 7 {
 8     int x, y;
 9     int v;
10 }e[10001000];
11 bool mycmp(node a, node b)
12 {
13     return a.v < b.v;
14 }
15 int getfa(int k)//找到祖先(最高级祖先) 
16 {
17     if(k == fa[k]) return k;
18     fa[k] = getfa(fa[k]);
19     return fa[k];
20 }
21 void merge(int x, int y)//合并x, y  
22 {
23     int fx = getfa(x);
24     int fy = getfa(y);
25     fa[x] = fy;
26 } 
27 bool judge(int x, int y)//判断是否在一个并查集中 
28 {
29     int fx = getfa(x);
30     int fy = getfa(y);
31     return (fx == fy);
32 }
33 int main()
34 {
35     //freopen("input.in","r",stdin);
36     //freopen("output.out","w",stdout);
37     scanf("%d%d",&n);
38     for(int i = 1;i < n;i++) 
39         scanf("%d%d%d", &e[i].x, &e[i].y, &e[i].v);
40     for(int i = 1; i <= n; i++)    fa[i] = i; //初始每个点都是一个集合
41     sort(e + 1, e + n + 1, mycmp); //边按升序排列
42     int cal = 0;
43     for(int i = 1;i <= n;i++)
44     {
45         int v = getfa(e[i].x);
46         int u = getfa(e[i].y);//寻找两个节点的祖先 
47         if(v != u)//如果不在一个并查集中 
48         {
49             merge(v, u);
50             sum += e[i].v;//最小生成树总长度 
51             if(++cal == n - 1)//如果已经做了N - 1次 
52             {
53                 printf("%d\n", sum);
54             }
55         } 
56     } 
57     return 0;
58 }

 

以上是关于kruskal算法的主要内容,如果未能解决你的问题,请参考以下文章

(最小生成树)Kruskal算法

POJ 1797 kruskal 算法

19.最优布线问题(kruskal算法)

caioj1090最小生成树之kruskal算法模板元问题

求最小生成树——Kruskal算法

43-Kruskal 算法