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

    Kruskal算法:首先按照边的权值进行从小到大排序,每次从剩余的边中选择权值最小的边且不会产生回路的边加入到生成树中,直到加入n-1条边就结束;

    算法难点在与如何判断是否会产生回路。这个可以通过并查集实现,将所有加入生成树的结点加入同一个集合;

    代码:

    #include <string.h>
    #include<iostream>
    #include<vector>
    #include<queue>
    #include <algorithm>
    using namespace std;
    struct edge{//边的结构
        int u;
        int v;
        int w;
    }e[100];
    int f[100];//并查集数组
    bool compare(struct edge a,struct edge b){//sort函数的比较器,实现边权从小到达排序
        return a.w<=b.w;
    }
    int getF(int x){//查找结点的根
        if(f[x]==x) return x;
        else {
            f[x]=getF(f[x]);//直接连接到根结点,实现路径压缩
            return f[x];
        }
    }
    bool unity(int a,int b){//联合所有加入生成树的结点
        int f1=getF(a);
        int f2=getF(b);
        if(f1!=f2){
            f[f1]=f2;
            return true;
        }
        return false;
    }
    
    int main()
    {
        int n,m;
        cin>>n>>m;
        for(int i=0;i<m;i++){//输入边信息
            cin>>e[i].u>>e[i].v>>e[i].w;
        }
        for(int i=0;i<100;i++){//初始化并查集
            f[i]=i;
        }
        sort(e,e+m,compare);//排序
        int munber=0,sum=0;
        for(int i=0;i<m;i++){//从小到大检测每一个结点是否可以加入生成树
            if(unity(e[i].u,e[i].v)){
                munber++;
                sum+=e[i].w;
            }
            if(munber==n-1) break;//当加入n-1条边,就可以结束
        }
        cout<<sum<<endl;
        return 0;
    }
  • 相关阅读:
    四则运算————javaweb版
    构建之法阅读笔记02
    十一周学习进度条
    软工概论-课堂练习:添加信息
    梦断代码阅读笔记01
    链接doc命令行的mysql的编码问题
    构建之法阅读笔记01
    第十周学习进度条
    web
    sql初——基础
  • 原文地址:https://www.cnblogs.com/zdl2234/p/10360728.html
Copyright © 2011-2022 走看看