今天上课讲到这道题,觉得十分有趣,写了个暴力然后就过挂了,查题解就找到了一个神奇的“B”算法(Boru˚vka)(Borůvka)(Boru˚vka)(这特么是什么啊!)

原题链接1

原题链接2

经过我在baidu上各位大佬的博客上的学习(多谢一位大佬的动态图),我终于明白了这个算法的工作原理。。。

接下来让我这位蒟蒻为各位光临这篇博客的大佬们讲解一下我所理解的这个算法

对于一个图


首先我们认为这整个图上的所有点都是一个独立的联通块。

接下来呢

每次让每一个连通块去寻找一条边权最小的边,并与连通块连接

从A号点开始,连6这条边

从B号点开始连1这条边

从C号点开始,连6这条边,由于6已和A连,所以无需再连边,AC两点连通

同理BD两点连通

从E号点出发,连2这条边

从F点出发,EF两点连通

从G号点出发,连5这条边。

从H号点出发,连15这条边。

第I号点连5这条边,与G号点相连。

从J号点出发,连4这条边。


从K号点出发,连10这条边。


最后就是从L点出发,JL两点相连。


然后我们就得到了这么几个联通块


再连接两个联通快之间的最短边(BC连边)

DF连边


KL连边

此时整张图就只剩下两个连通块了

再连接他们之间的最短边

然后我们就得到了一个完整的联通图


将点集AAA,VVV分为SSS和V−SV-SV−S,一端在SSS内另一端在V−SV-SV−S内边权最小的边,一定会在最小生成树中。

复杂度分析:

每次连通块都减少至原来的一半,每一次都要遍历每一条边,所以其复杂度为O(Elog⁡V)O(E\log V)O(ElogV) EEE为边的个数,VVV为点数

code:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int twx=2e5+100;
const int INF=0x3f3f3f3f;
ll read()
{ll sum=0;ll flag=1;char c=getchar();while(c<'0'||c>'9'){if(c=='-'){flag=-1;}c=getchar();}while(c>='0'&&c<='9'){sum=((sum*10)+c-'0');c=getchar();}return sum*flag;
}
struct LV
{int x,y,w;
}edge[twx];
int n,m;
int d[twx];// 各子树的最小连外边的权值
int e[twx];// 各子树的最小连外边的索引
bool v[twx];// 防止边重复统计
int fa[twx];
int getfa(int x)
{return x==fa[x]?x:(fa[x]=getfa(fa[x]));
}
void add(int x,int y)
{fa[getfa(x)]=getfa(y);
}
void init()
{n=read();m=read();for(int i=1;i<=m;i++){edge[i].x=read();edge[i].y=read();edge[i].w=read();}
}
int Boruvka()
{int tot=0;for(int i=1;i<=n;i++){fa[i]=i;}while(1){int cur=0;for(int i=1;i<=n;i++){d[i]=INF;}for(int i=1;i<=m;i++)  {int a=getfa(edge[i].x);int b=getfa(edge[i].y);int c=edge[i].w;if(a==b){continue ;}cur++;if(c<d[a]||c==d[a]&&i<e[a]){d[a]=c;e[a]=i;}if(c<d[b]||c==d[b]&&i<e[b]){d[b]=c;e[b]=i;}}if(!cur){break ;}for(int i=1;i<=n;i++){if(d[i]!=INF&&!v[e[i]]){add(edge[e[i]].x,edge[e[i]].y);tot+=edge[e[i]].w;v[e[i]]=true;}}}return tot;
}
void print()
{printf("%d",Boruvka());
}
int main()
{//freopen(".in","r",stdin);//freopen(".out","w",stdout);init();print();return 0;
}

这个模板能拿去AluoguP3366了

上了第一页QAQ

经过实际测试,发现这个算法在一些情况下不如kruskalkruskalkruskal,但是在点少边多的情况下还是能比过kruskalkruskalkruskal的

这题呢就是用了这种思想,每次进行合并。

发现每次合并的集合都是在二进制位下最高位的1的集合,所以从上往下操作,从最高位把集合分开,然后查询两个集合的最小连边。

将所有元素按从小到大排序加入到Trie树,这样的话一个集合内的元素就在一个连续的区间里了

最后就是遍历一遍Trie树统计出答案就行了
code:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int twx=2e5+100;
const int nn=15;
const int INF=0x3f3f3f3f;
ll read()
{ll sum=0;ll flag=1;char c=getchar();while(c<'0'||c>'9'){if(c=='-'){flag=-1;}c=getchar();}while(c>='0'&&c<='9'){sum=((sum*10)+c-'0');c=getchar();}return sum*flag;
}
int n;
int a[twx];
int gen;
int L[twx*nn];
int R[twx*nn];
int ch[twx*nn][2];
int tot;
void Insert(int &now,int x,int dd)
{if(!now){now=++tot;}L[now]=min(L[now],x);R[now]=max(R[now],x);if(dd<0){return ;}int asd=a[x]>>dd&1;Insert(ch[now][asd],x,dd-1);
}
int add(int now,int val,int dd)
{if(dd<0){return 0;}int asd=val>>dd&1;if(ch[now][asd]){return add(ch[now][asd],val,dd-1);}else{return add(ch[now][asd^1],val,dd-1)+(1<<dd);}
}
ll work(int now,int dd)
{if(dd<0){return 0;}if(R[ch[now][0]]&&R[ch[now][1]]){int asd=INF;for(int i=L[ch[now][0]];i<=R[ch[now][0]];i++){asd=min(asd,add(ch[now][1],a[i],dd-1)); }return work(ch[now][0],dd-1)+work(ch[now][1],dd-1)+asd+(1<<dd);}if(R[ch[now][0]]){return work(ch[now][0],dd-1);}if(R[ch[now][1]]){return work(ch[now][1],dd-1);}return 0;
}
void init()
{n=read();for(int i=1;i<=n;i++){a[i]=read();}sort(a+1,a+n+1);memset(L,0x3f,sizeof(L));
}
void print()
{for(int i=1;i<=n;i++){Insert(gen,i,30);}printf("%lld",work(gen,30));
}
int main()
{//freopen(".in","r",stdin);//freopen(".out","w",stdout);init();print();return 0;
}

这个是我磨了一天才弄出来的,在交CF的时候有好多稀奇古怪的错误
最后放张截图:

普天同庆!普天同庆!普天同庆!

CF888G - Xor-MST(顺带学习Borůvka算法)相关推荐

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

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

  2. 强化学习(五) - 时序差分学习(Temporal-Difference Learning)及其实例----Sarsa算法, Q学习, 期望Sarsa算法

    强化学习(五) - 时序差分学习(Temporal-Difference Learning)及其实例 5.1 TD预测 例5.1 回家时间的估计 5.2 TD预测方法的优势 例5.2 随机移动 5.3 ...

  3. 04 集成学习 - Boosting - AdaBoost算法构建

    03 集成学习 - Boosting - AdaBoost算法原理 十.AdaBoost算法构建 上一章最后说明了每个基模型的权值α是如何求得的,于是我就可以对模型进行更新操作了. 构建过程一 1.假 ...

  4. 集成学习、Bagging算法、Bagging+Pasting、随机森林、极端随机树集成(Extra-trees)、特征重要度、包外评估

    集成学习.Bagging算法.Bagging+Pasting.随机森林.极端随机树集成(Extra-trees).特征重要度.包外评估 目录

  5. 好久没有看到这么有建设性德文章,由衷地赞叹《知其所以然地学习(以算法学习为例)》-By 刘未鹏(pongba)

    知其所以然地学习(以算法学习为例) By 刘未鹏(pongba) C++的罗浮宫(http://blog.csdn.net/pongba) Updated(2008-7-24):更新见正文部分,有标注 ...

  6. 贝叶斯网络结构学习之K2算法(基于FullBNT-1.0.4的MATLAB实现)

    题目:贝叶斯网络结构学习之K2算法(基于FullBNT-1.0.4的MATLAB实现) 有关贝叶斯网络结构学习的一基本概念可以参考:贝叶斯网络结构学习方法简介 有关函数输入输出参数的解释可以参考:贝叶 ...

  7. 特征点检测学习_2(surf算法)

    特征点检测学习_2(surf算法) 在上篇博客特征点检测学习_1(sift算法) 中简单介绍了经典的sift算法,sift算法比较稳定,检测到的特征点也比较多,其最大的确定是计算复杂度较高.后面有不少 ...

  8. Surf算法学习心得(一)——算法原理

    Surf算法学习心得(一)--算法原理 写在前面的话: Surf算法是对Sift算法的一种改进,主要是在算法的执行效率上,比Sift算法来讲运行更快!由于我也是初学者,刚刚才开始研究这个算法,然而网上 ...

  9. 专访DeepID发明者孙祎:关于深度学习与人脸算法的深层思考

    专访DeepID发明者孙祎:关于深度学习与人脸算法的深层思考 发表于2015-11-18 09:51 作者周建丁 CNN卷积神经网络DeepID人脸算法深度学习孙祎Linkface 摘要:DeepID ...

  10. 【StatLearn】统计学习中knn算法实验(2)

    接着统计学习中knn算法实验(1)的内容 Problem: Explore the data before classification using summary statistics orvisu ...

最新文章

  1. php接入微信运动计步功能,运动计步,微信运动究竟靠不靠谱?
  2. hbase 读写调优_hbase性能调优
  3. petalinux zynq spi_ZYNQ 系列 01 | PL 实现按键控制 LED(1)
  4. Hbase hbck2下载编译和基本使用
  5. CentOS虚拟机时间同步
  6. Zabbix探索:无法获取Windows主机CPU利用率、负载等问题处理
  7. mysql references关键字_mysql关键字有哪些?
  8. 明小子mysql_安全狗最新版SQL注入防护多种方式bypass(简简单单/各种数据库通用)...
  9. 如何更改html的默认应用,win10如何修改默认应用
  10. 无奇不有,20款国外便携式智能手机充电器
  11. endnote中文格式参考文献标注
  12. VNC_Linux环境服务安装、配置与使用
  13. android wifi分享文件下载,WiFi文件共享
  14. python实现排序算法lowb三人组之选择排序
  15. Fluent compiled 失败
  16. 生物识别设备有问题_有您数据的生物识别
  17. FastGCNL:FAST LEARNING WITH GRAPH CONVOLUTIONAL NETWORKS VIA IMPORTANCE SAMPLING
  18. 罗振宇 知识就是力量之 怎样重新获得别人的信任
  19. UVaOJ572---Oil Deposits
  20. 1164 -- 判断三角形类型

热门文章

  1. 软考中级-软件设计师 复习指南(2021年11月已通过)
  2. 深交所互动平台_“国六”标准实施在即,互动平台“抖出”大波概念股
  3. 从数据流角度管窥 Moya 的实现(二):处理响应
  4. 列表解析式与生成器表达式
  5. R-CNN文章详细解读
  6. [转]让你的网页文本框增加光晕效果与提示,水印(类似QQ2011)
  7. 2020版本kali安装
  8. ABAP 数据的基本输出Write简单用法
  9. 关于360评估的全面介绍
  10. 企业遇到什么问题一定要用360评估?