zoukankan      html  css  js  c++  java
  • 图的最小生成树——Kruskal算法

    Kruskal算法

    图的最小生成树的算法之一,运用并查集思想来求出最小生成树。

    基本思路就是把所有边从小到大排序,依次遍历这些边。如果这条边所连接的两个点在一个连通块里,遍历下一条边,如果不在,就把这条边加入连通块,这样就可以保证生成树的边权最小。

    我们使用并查集来判断两个点是否在同一个连通块里,如果在,他们的find会相同,否则不在。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define N 42000
     4 using namespace std;
     5 struct hehe{
     6     int a1;
     7     int b1;
     8     int c1;
     9 }edge[N];
    10 int n,m,a,b,c,father[N],num,tot,k;
    11 int cmp(hehe x,hehe y){
    12     return x.c1<y.c1;
    13 }
    14 int find(int x){
    15     if(father[x]!=x)
    16         father[x]=find(father[x]);
    17     return father[x];
    18 }
    19 int main(){
    20     scanf("%d%d",&n,&m);
    21     for(int i=1;i<=m;++i){
    22         scanf("%d%d%d",&a,&b,&c);
    23         edge[++num].a1=a;
    24         edge[num].b1=b;
    25         edge[num].c1=c;
    26     }
    27     for(int i=1;i<=n;++i)
    28         father[i]=i;
    29     sort(edge+1,edge+m+1,cmp);
    30     for(int i=1;i<=m;++i)
    31         if(find(edge[i].a1)!=find(edge[i].b1)){
    32             father[edge[i].a1]=edge[i].b1;
    33             tot+=edge[i].c1;
    34             k++;
    35             if(k==n-1)
    36                 break;
    37         }
    38     printf("%d",tot);
    39     return 0;
    40 }
    View Code
  • 相关阅读:
    OI数学知识清单
    线段树入门教程
    扩展欧几里得定理基础讲解 代码及证明
    名字竞技场 V3.0
    可持久化线段树(主席树)新手向教程
    矩阵乘法浅析
    [Luogu] P1233 木棍加工
    高斯消元 模板
    位运算技巧
    [ZJOJ] 5794 2018.08.10【2018提高组】模拟A组&省选 旅行
  • 原文地址:https://www.cnblogs.com/jsawz/p/6819468.html
Copyright © 2011-2022 走看看