当我认为最MST(最小生成树)已经没有什么学的了,才发现世界上还有个这个kruskal和prim结合的玩意

Borůvka 运用并查集的思想,先将每一个初始点集初始化为有且只有自己的点集,然后每一次合并都从所有的独立集合出发,找到一条权值最小的(权值相同,则编号最小)连向其他集合的边,然后合并集合,很容易看出,每次合并都会使集合总数少一半,合并次数大致为log n

相比之下,Borůvka的合并次数要远远少于其他两个常用的MST算法,但是,毕竟不是一般情况下最快的,但是在求解一些个别的(例如边数多,点数较少的完全图)问题有奇效

 luogu MST的例题,过不去,最后一个点会T,毕竟Borůvka是用来解决完全图的,并不是一般情况下最快的

 1 #include "bits/stdc++.h"
2 using namespace std;
3 #define LL long long
4 const int N = 2e5 + 10;
5 int n,m;
6 int s[N],t[N],w[N];
7 struct Boruvka
8 {
9 int f[N],use_edge[N],best[N];
10 void init()
11 {
12 for(int i = 1;i <= n;i ++) f[i] = i,best[i] = 0;
13 for(int i = 1;i <= m;i ++) use_edge[i] = 0;
14 }
15 int find(int x)
16 {
17 return f[x] == x ? x : (f[x] = find(f[x]));
18 }
19 int better(int x,int y)
20 {
21 if(!y) return 1;
22 if(w[x] < w[y]) return 1;
23 return x < y;
24 }
25 LL get(void)
26 {
27 int merge=0;
28 LL sum=0;
29 while(merge != n - 1)
30 {
31 for(int i = 1;i <= m;i ++)
32 {
33 if(use_edge[i]) continue;
34 int x = find(s[i]),y = find(t[i]);
35 if(x == y) continue;
36 if(better(i,best[x])) best[x] = i;
37 if(better(i,best[y])) best[y] = i;
38 }
39 for(int i = 1;i <= n;i ++)
40 {
41 if(best[i]){
42 int x = find(s[best[i]]),y = find(t[best[i]]);
43 if(x != y){
44 use_edge[best[i]] = 1;
45 f[x] = y;
46 merge ++;
47 sum += w[best[i]];
48 }
49 best[i] = 0;
50 }
51 }
52 }
53 return sum;
54 }
55 }g;
56 int main(void)
57 {
58 ios::sync_with_stdio(false);
59 cin >> n >> m;
60 for(int i = 1;i <= m;i ++) cin >> s[i] >> t[i] >> w[i];
61 g.init();
62 cout << g.get() << '\n';
63 return 0;
64 }

luogu CF888G XOR-MST

很经典的题,题目大意为:

给定一个n个节点的完全图,每个节点有个编号ai,节点i和节点j之间边的权值为ai xor aj,求该图的最小生成树的权值和。

完全图,优先考虑Borůvka

需要在n log n左右的时间中求出每个连通块最小的连接的边,在这道题中边权可以通过点权求出
但是,这是不能直接算出每条边的边权的,因为这一看就是会超时的

所以根据二进制的性质,考虑建对全局建一个01trie,然后再给每一个连通块建一个tire,Borůvka算法每一次合并两个连通块,就合并两个tire,再在trie上维护子树的size,点权异或最小值就直接在全局trie与当前连通块的size作差得到树上贪心即可

总共会迭代log n次,总时间复杂度为O(n logn logsize ),空间复杂度为O(n log size)

 code,仅供参考,没有注释

 1 #include"bits/stdc++.h"
2 #define ll long long
3 #define inl inline
4 #define reg register
5 #define ls ch[now][0]
6 #define rs ch[now][1]
7 using namespace std;
8 const int N = 2e5 + 10;
9 const int inf = 0x7ffffff;
10
11 int L[N * 40],R[N * 40];
12 int ch[N * 40][2];
13 int tot;
14 int n,a[N],root;
15 inl int read(void)
16 {
17 int x = 0,f = 1;char ch = getchar();
18 while(!isdigit(ch)) f = ch == '-' ? - 1 : f,ch = getchar();
19 while(isdigit(ch)) x = (x << 3) + (x << 1) + ch - '0',ch = getchar();
20 return x * f;
21 }
22 inl void Insert(int &now,int x,int dep)
23 {
24 if(!now) now = ++ tot;
25 L[now] = min(L[now],x),R[now] = max(R[now],x);
26 if(dep < 0) return;
27 int bit = a[x] >> dep & 1;
28 Insert(ch[now][bit],x,dep - 1);
29 }
30 inl int query(int now,int val,int dep)
31 {
32 if(dep < 0) return 0;
33 int bit = val >> dep & 1;
34 if(ch[now][bit]) return query(ch[now][bit],val,dep - 1);
35 else return query(ch[now][bit ^ 1],val,dep - 1) + (1 << dep);
36 }
37 inl ll dfs(int now,int dep)
38 {
39 if(dep < 0) return 0;
40 if(R[ls] && R[rs])
41 {
42 int minn = inf;
43 for(int i = L[ls];i <= R[ls];i ++) minn = min(minn,query(rs,a[i],dep - 1));
44 return dfs(ls,dep - 1) + dfs(rs,dep - 1)+ minn + (1 << dep);
45 }
46 if(R[ls]) return dfs(ls,dep - 1);
47 if(R[rs]) return dfs(rs,dep - 1);
48 return 0;
49 }
50 int main(void)
51 {
52 n = read();
53 for(int i = 1;i <= n;i ++) a[i] = read();
54 sort(a + 1,a + 1 + n);
55 memset(L,0x3f,sizeof(L));
56 for(int i = 1;i <= n;i ++) Insert(root,i,30);
57 printf("%lld\n",dfs(root,30));
58 return 0;
59 }

Borůvka MST算法的更多相关文章

  1. Borůvka (Sollin) 算法求 MST 最小生成树

    基本思路: 用定点数组记录每个子树的最近邻居. 对于每一条边进行处理: 如果这条边连成的两个顶点同属于一个集合,则不处理,否则检测这条边连接的两个子树,如果是连接这两个子树的最小边,则更新 (合并). ...

  2. Codeforces.888G.Xor-MST(Borůvka算法求MST 贪心 Trie)

    题目链接 \(Description\) 有一张\(n\)个点的完全图,每个点的权值为\(a_i\),两个点之间的边权为\(a_i\ xor\ a_j\).求该图的最小生成树. \(n\leq2*10 ...

  3. 【做题】CSA72G - MST and Rectangles——Borůvka&线段树

    原文链接 https://www.cnblogs.com/cly-none/p/CSA72G.html 题意:有一个\(n \times n\)的矩阵\(A\),\(m\)次操作,每次在\(A\)上三 ...

  4. 最小生成树-Borůvka算法

    一般求最小生成树的时候,最流行的是Kruskal算法,一种基于拟阵证明的贪心,通过给边排序再扫描一次边集,利用并查集优化得到,复杂度为\(O(ElogE)\).另一种用得比较少的是Prim算法,利用优 ...

  5. Kruskal vs Borůvka

    做了个对比.Borůvka算法对于稠密图效果特别好.这两个都是求生成森林的算法.Prim+heap+tarjan过于难写不写了. V=200,E=1000 Kruskal method 4875048 ...

  6. Borůvka algorithm

    Borůvka algorithm 我好无聊啊,直接把wiki的算法介绍翻译一下把. wiki关于Borůvka algorithm的链接:链接 Borůvka algorithm是一个在所有边权都是 ...

  7. 最小生成树MST算法(Prim、Kruskal)

    最小生成树MST(Minimum Spanning Tree) (1)概念 一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边,所谓一个 ...

  8. NOIp 图论算法专题总结 (1):最短路、最小生成树、最近公共祖先

    系列索引: NOIp 图论算法专题总结 (1) NOIp 图论算法专题总结 (2) NOIp 图论算法专题总结 (3) 最短路 Floyd 基本思路:枚举所有点与点的中点,如果从中点走最短,更新两点间 ...

  9. 「CSA72」MST

    「CSA72」MST 题目大意:有一个大小为 \(n\) 的无向完全图,\(x, y\) 之间的边权值为 \(a[\min(x,y)][\max(x,y)]\) ,初始为0,进行 \(m\) 次修改, ...

  10. 最小生成树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind

    最小支撑树树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind 最小支撑树树 前几节中介绍的算法都是针对无权图的,本节将介绍带权图的最小 ...

随机推荐

  1. 2024 SemEval 冠军

    SemEval Task10,本质是一个文本分类的任务,有三个子任务,论文摘要如下:在多维对话中,情绪不仅作为情感交流的重要中介者,还承载着丰富的信息.因此,准确识别交流者的情绪并理解情绪变化的触发因 ...

  2. Spring Boot 2.0 新人会踩的坑--启动报404错误

    转载自:http://www.javaman.cn/channels/sb2 启动程序,验证效果 根据图示,点击按钮,来启动 Spring Boot Web 程序, 查看控制台输出: . ____ _ ...

  3. Hibernate之list和iterator

    在Hibernate3中将Session.find(),Session.iterator()换成:session.createQuery().list(),session.createQuery(). ...

  4. RAG 范式、技术和趋势

    这里分享同济大学 Haofen Wang的关于检索增强生成的报告:<Retrieval-Augmented Generation (RAG): Paradigms, Technologies, ...

  5. C程序问题归纳(static,auto,register,extern,程序内存分布图,linux下程序的执行过程......)(二)

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  6. 【leetcode https://leetcode.cn/problems/count-integers-in-intervals/】 线段树

    leetccode count-integers-in-intervals 线段树解决: class CountIntervals { Seg root; public CountIntervals( ...

  7. 记录--你还在使用websocket实现实时消息推送吗?

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 前言 在日常的开发中,我们经常能碰见服务端需要主动推送给客户端数据的业务场景,比如数据大屏的实时数据,比如消息中心的未读消息,比如聊天功能 ...

  8. Python 合并Excel文件(Excel文件多sheet)

    一.Python合并Excel文件多sheet<方法1> import os import pandas as pd # 指定包含Excel文件的文件夹路径 folder_path = ' ...

  9. 快速上手系列:传智播客Java基础学习笔记

    配置环境,把JDK的bin所在路径复制到Path,末尾加; 基本语法 一  常见的DOS命令     盘符的切换 d:回车     目录的进入 cd javase                  c ...

  10. 并发CPU伪共享及优化

    伪共享 缓存系统中是以缓存行(cache line)为单位存储的.缓存行是2的整数幂个连续字节,一般为32-256个字节.最常见的缓存行大小是64个字节.当多线程修改互相独立的变量时,如果这些变量共享 ...