zoukankan      html  css  js  c++  java
  • (最小生成树)Kruskal算法

                (最小生成树)Kruskal算法

      

      Kruskal算法的高效实现需要一种称作并查集的结构。。

      Kruskal算法的过程:
      (1) 将全部边按照权值由小到大排序。
       (2) 按顺序(边权由小到大的顺序)考虑每条边,只要这条边和我们已经选择的边不构成圈,就保留这条边,否则放弃这条边。

      算法 成功选择(n-1)条边后,形成一棵最小生成树,当然如果算法无法选择出(n-1)条边,则说明原图不连通。

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

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

      否则,不形成环。

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

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

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 
     4 using namespace std;
     5 int n, m, ans = 0, tmp = 1;
     6 int fa[1000100];
     7 int getfa(int x){
     8     if(x == fa[x]) return x;
     9     else return fa[x] = getfa(fa[x]);
    10 }
    11 struct node{
    12     int x, y, z;
    13 } e[1000100];
    14 bool mycmp(node a, node b){
    15     return a.z < b.z;
    16 }
    17 int main(){
    18 //    freopen("input.in","r",stdin);
    19 //    freopen("output.out","w",stdout);
    20     scanf("%d%d", &n, &m);
    21     for(int i = 1;i <= m;i++){
    22         scanf("%d%d%d", &e[i].x, &e[i].y, &e[i].z);
    23     }
    24     sort(e+1, e+m+1, mycmp);
    25     for(int i = 1;i <= n;i++) fa[i] = i;
    26     for(int i = 1;i <= m;i++){
    27         int fx = getfa(e[i].x);
    28         int fy = getfa(e[i].y);
    29         if(fx == fy) continue;
    30         fa[fx] = fy;
    31         ans += e[i].z;
    32         tmp ++;
    33     }
    34     if(tmp < n) printf("orz
    ");
    35     else printf("%d
    ", ans);
    36     return 0;
    37 }
  • 相关阅读:
    互斥锁Mutex与信号量Semaphore的区别
    c/c++强制类型转换
    c++中的隐藏、重载、覆盖(重写)
    运算符重载详解
    类的大小
    C++ static、const和static const 以及它们的初始化
    一种隐蔽性较高的Java ConcurrentModificationException异常场景
    Java编码常见的Log日志打印问题
    Java编程常见缺陷汇总(一)
    Java字符串连接的多种实现方法及效率对比
  • 原文地址:https://www.cnblogs.com/smilke/p/10758196.html
Copyright © 2011-2022 走看看