• 【模板】最小生成树(kruscal)


    //洛谷P3366

    (其中所应用的并查集原理请见http://www.cnblogs.com/XjzLing/p/7943363.html

    这里选用Kruscal的方法:先将每一个点用并查集记录它们的祖先,用fa[i]来表示

    然后将边按照权重,从小到大排序,这里选用sort的cmp。

    然后,从小到大遍历边权,如果遍历到一条边的所连的两个结点不在同一集合,就将这两个点连上,ans+=G[i].val即可。

    等连到n-1条边时,该图已经成为一颗树,即输出答案

    #include<algorithm>
    #include<iostream>
    #include<cstdio>
    #define maxn 200000 + 10
    using namespace std;
    int n,m,ans,num;
    int fa[maxn];
    struct edge{
        int frm,to,val;
    }G[maxn];
    //记录边的信息:起点,终点,权 
    void init(){
        for(int i=1;i<=n;i++) fa[i]=i;
    }//并查集预处理 
    bool cmp(edge a,edge b){
        return a.val<b.val;
    }// 用于sort的cmp函数 
    int find(int x){
        if(x==fa[x]) return x;
        else return fa[x]=find(fa[x]);
    }//并查集找祖先 
    bool merge(edge a){
        if(find(a.frm)!=find(a.to)){
            fa[fa[a.to]]=find(a.frm);
            return true;
        }
        return false;
    }//并查集连边 
    int main(){
        scanf("%d%d",&n,&m);
        init();
        for(int i=1;i<=m;i++) scanf("%d%d%d",&G[i].frm,&G[i].to,&G[i].val);
        sort(G,G+m,cmp);//将边权从小到大排序 
        for(int i=1;i<=m && num<n-1;i++)
            if(merge(G[i])){
                ans+=G[i].val;
                num++;
            }//Kruscal操作 
        if(num==n-1) printf("%d",ans);
        else printf("orz");
        return 0;
    }
  • 相关阅读:
    ES6新语法之---块作用域let/const(2)
    sass变量
    Ruby(或cmd中)输入命令行编译sass
    sass的安装
    鼠标滚动兼容
    HTML5新标签兼容——> <!--<if lt IE 9><!endif-->
    #include stdio.h(7)
    #include stdio.h(6)
    #include stdio.h(5)
    #include stdio.h(3)
  • 原文地址:https://www.cnblogs.com/XjzLing/p/7943259.html
Copyright © 2020-2023  润新知