码迷,mamicode.com
首页 > 编程语言 > 详细

(最小生成树)Kruskal算法

时间:2019-04-23 19:09:44      阅读:123      评论:0      收藏:0      [点我收藏+]

标签:its   i++   算法   注释   cal   oid   int   tput   ==   

            (最小生成树)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算法

标签:its   i++   算法   注释   cal   oid   int   tput   ==   

原文地址:https://www.cnblogs.com/smilke/p/10758196.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!