首页 > 其他分享 >Diary - 2024.12.05

Diary - 2024.12.05

时间:2024-12-05 18:44:12浏览次数:6  
标签:2024.12 连通 05 复杂度 最小 sqrt Diary mathcal boruvka

哥我真的佩服你了,,,
你说物理老师上完课说的给一两天整理的意思又没有可能是指拿时间整理一下然后等老师来讲,
而不是做完作业直接开跑看课,然后让大家追赶你的步伐,,,
有点流汗了,感觉现在一天学了好多脑子要爆掉了,然后我还得快点做作业来跟上你看课的速度,,,

哥我错了,我是菜比行吗,,,

在您的引领之下,仅用四天就把物理补完了开始要回去上物理课了。
甚至是只回去上物理,有点搞笑了。

但是又要回班上了,我要玉玉了。


实际上 boruvka 是十分优美的一个东西。

虽然往往只直接把复杂度当作 \(\mathcal{O}(f(n, m)\log n)\)(\(f(n, m)\) 通常就是一个关于 \(n, m\) 的多项式,视题目及做法而定),但是还是要考虑下为什么的。
这是因为在最劣情况下如果每次找最小边都是双向边,所以才会使得每次连通块数 \(/ 2\) 的,轮数 \(\mathcal{O}(\log n)\)。

但是实际上抛弃死板的复杂度,从每一步去入手能得到更优美的性质。
其实也就是去深究一下每一步缩连通块的情况。

例题:Codeforces 2041N(口胡还在发力)。

这种差不多的完全图,肯定是还要考虑下 boruvka 的。
然后分析 boruvka 第一轮点 \(i\) 找到的对应的最短边 \((i, j)\) 的 \(j\) 的性质。
那么因为边权是 \(a_i + a_j\) 的形式,那就是要最小化 \(a_j\)。
定义 \(S_i = \{1, 2, \cdots, n\} - \{j | (i, j)\in E\} - \{i\}\)(\(E\) 为被删掉的边集),那么 \(j\) 肯定满足 \(j\in S_i, a_j = \min_{k\in S_i}(a_k)\)。

于是一个直观的过程就是先按 \(a_i\) 从小到大排序。
对于每一个 \(i\),\(j = 1\) 开始往后扫,直到 \(j\not = i, (i, j)\not \in S\),那么第一轮的连边就是 \((i, j)\)。

这个时候令 \(b_i = j - 1\),那么应当有 \(\sum\limits_{i = 1}^n b_i\le |S| = m\),那么这说明了暴力扫的复杂度是对的(均摊)且 \(b_i\) 只会有 \(\mathcal{O}(\sqrt m)\) 种本质不同值。
(实际上有点小问题,因为忽略掉了 \(i = j\) 时凭空多出的一条被删的边,但是实际上这个情况也只会出现 \(\mathcal{O}(\sqrt{m})\) 次,是 \(\mathcal{O}(\sqrt{m + \sqrt m})\),但是直接分析成 \(\mathcal{O}(\sqrt{n + m})\) 问题也不大。)

那么这说明了在第一轮的缩点后,实际上的连通块只会有 \(\mathcal{O}(\sqrt m)\) 个(连通块应当关于 \(b_i\) 是个类菊花的样子,\(b_i\) 为根),而且 \(\operatorname{deg}_i > 1\) 的点此时只会有 \(\sqrt{m}\) 个。

于是说在后面的 \(\mathcal{O}(\sqrt{m})\) 个连通块间跑出的最小生成树也只会有 \(\mathcal{O}(\sqrt{m})\) 条边,那么在这一阶段产生的 \(\operatorname{deg}_i > 1\) 的点的数量也是 \(\mathcal{O}(\sqrt m)\) 级别的。

于是整合起来,\(\operatorname{deg}_i > 1\) 的点的数量是 \(\mathcal{O}(\sqrt m)\) 的。

那么对于 \(\operatorname{deg}_i = 1\) 的叶子,最小生成树内删掉了对树的形态没有影响。
于是只需要对于 \(\mathcal{O}(\sqrt m)\) 个非叶子的点直接删掉重新跑一遍最小生成树就行了。

当然这只是大体思路,还需要讨论下细节问题。

Q:如何 \(\mathcal{O}(n + m)\) 求最小生成树?
首先第一轮的 boruvka 找最小值是 \(\mathcal{O}(n + m)\) 的,排序可以用基数排序做到 \(\mathcal{O}(n)\),后面的连边可以在最后连出的环找一下环上最大权边,断掉即可,也是 \(\mathcal{O}(n)\) 的(实际上想直接用并查集 \(\alpha(n)\) 应该也是可以的吧)。
那么对于后面 \(\mathcal{O}(\sqrt m)\) 个连通块的最小生成树只需要在 \(\mathcal{O}(n + m)\) 内找到两两连通块间的最小边权,然后跑 \(\mathcal{O}(n^2 + m)\) 的 prim 就可以了(这里的 \(n, m\) 指的是缩完连通块的图的点数边数,所以复杂度应是 \(\mathcal{O}(m)\) 的)。

Q:那如何 \(\mathcal{O}(n + m)\) 找到两两连通块间的最小边权。
好问题……
首先可以在块内先按 \(a_i\) 排好序。
首先一个暴力的想法是对于每个点都找一下每个连通块的最小值,这个依然均摊分析到 \(\mathcal{O}(n + m)\)。
最后在连通块内合并信息,但是这样就 \(\mathcal{O}(m\sqrt{m})\) 了……
考虑到块内其实还是有很多信息是无用的。
考虑直接枚举两个块,让其中一个块 \(a_i\) 从小到大遍历 \(i\),那么对应在另一个块找到于其的最小权 \(a_j\)。
注意到的是因为 \(a_i\) 不降,那么如果第一个块后面才枚举到的 \(a_k\ge a_i\),实际上在第二个块枚举到 \(j\) 之前就可以了,因为 \(a_k + a_j\ge a_i + a_j\),\(j\) 往后还更大。
实际上一个更偷懒的想法是如果找到 \(a_i\) 能和第二个块的最小值连边就直接不往后枚举了,正确性显然,就是上面说到的弱化。
考虑分析复杂度,那么可以拆分为,跳过(被删掉)的边数 + 在第一个块遍历到的点数(对于这些点确定一条边出来)。
那么被跳过的边肯定是不超过 \(m\) 条的。
对于遍历到的点数,拆分成,前缀不能与另一个块最小值有连边的点数 + 与另一个块最小值有连边的点数。
对于第一部分,依然是均摊分析被跳过的边,是 \(\mathcal{O}(m)\) 的;对于第二部分,两个连通块间只会存在一次,因为连通块数是 \(\mathcal{O}(\sqrt{m})\) 的,最后也是 \(\mathcal{O}(m)\) 的。

于是最后时间复杂度 \(\mathcal{O}((n + m)\sqrt{m})\),看起来好像就完结撒花了/庆祝。
实际上实现可能还是有点难度的,加上我是口胡哥,就没有代码了。

byd 差点给删了,吓死我了。

我严重怀疑这题是那位 tmt514 出的。
之前 boruvka 就搜到过他的文章(其实是 boruvka 分治,但是我现在都还没看)。
而且里面有个专门的最小生成树板块。
而且里面还有个 Borůvka-Prim 演算法 感觉就是和这题大致过程一样,先 boruvka 在 prim 阿。
参考链接:https://tmt514.github.io/algorithm-analysis/minimum-spanning-tree/boruvka-prim.html


突然发现似乎我的摆都是因为记性不好。


回到上文,boruvka 分治感觉在序列上没有什么用阿。
感觉这个结构还不是很好维护,不如在序列上面建 kruskal 树。

但是序列上的 kruskal 树是不是就是笛卡尔树来着。
我草我现在才发现,是不是没救了。

标签:2024.12,连通,05,复杂度,最小,sqrt,Diary,mathcal,boruvka
From: https://www.cnblogs.com/rizynvu/p/18588522

相关文章

  • 工作日记_241205
    工作日记241205写VHDL中,需要写两段很长的手动赋值语句,如PM_0<=sigma_0;PM_1<=sigma_1;PM_2<=sigma_2;...PM_100<=sigma_100;再反过来赋值:sigma_0<=PM_0;sigma_1<=PM_1;sigma_2<=PM_2;...sigma_100<=PM_100;由于这事情很繁琐。复制粘贴倒还好,还......
  • 05.数组概述
    Java内存堆​ 存放所有new出来的对象和数组​ 可以被所有的线程共享,不会存放别的对象引用栈​ 存放基本变量类型(会包含这个基本类型的具体数值)​ 引用对象的变量(会存放这个引用在堆里面的具体地址)方法区​ 可以被所有的线程共享​ 包含了所有的class和static变量数......
  • 05-字符串
    05-字符串由英文双引号(DoubleQuote)引起来的一串字符称为字符串字面值(StringLiteral),或者简称字符串。【注】C语言中没有字符串类型!!!"abcdefghijklmnopqrstuvwxyz"一、证明(\0)字符串的结束标志是一个\0(转义字符),被隐藏起来了。【注】在计算字符串长度的时候\0是结束标志,不......
  • 2024.12.4 周三
    2024.12.4周三Q1.1000给定01串,操作:选择l,r,将s[r]放到s[l]前:s[l]s[l+1]...s[r-1]s[r]->s[r]s[l]s[l+1]...s[r-1],代价为r-l+1/区间长度。问最小代价将01串由小到大排序。Q2.1300给定2行'<''>'组成的字符串,起点[1,1],可选4个方向走一步,然后必须根据所在字符走一步。问是......
  • 【每日一题】20241205
    【每日一题】已知非零向量\(\bm{a}\),\(\bm{b}\)满足\(|\bm{a}|=2|\bm{b}|\),且\((\bm{a}-\bm{b})\perp\bm{b}\),则\(\bm{a}\)与\(\bm{b}\)夹角的余弦值为_________.[题目来源:]设\(\alpha\)为锐角,若\(\cos\left(\alpha+\frac\pi6\right)=\frac45,则\sin......
  • 链接MySQL报错2059 -Authentication plugin ‘caching sha2 password‘ cannot be loa
    1.报错内容: 2059-Authenticationplugin'cachingsha2password'cannotbeloaded2.报错截图:3.原因分析:如上图的报错提示可知,报错原因是caching_sha2_password不能加载。在MySQL8.0及以上版本中,默认的用户密码认证插件是'caching_sha2_password',而在MySQL5.7及以下......
  • hot100-一刷-05普通数组(共5道题)
    53.最大子数组和题目链接题目描述代码实现分析:贪心:只要当前累加的值≥0,就是对整个结果是有贡献的,但是一旦<0,就拖累了整体结果。sum就是用来计算某一段上的局部总和。ans用来计算最终答案,取每一段里最大的。sum一旦小于0,则需要清空这一段。动态规划:代码://贪心classSo......
  • 【Vulkan入门】05-开启Vulkan的validation
    目录先叨叨关键函数和APIVulkanEnv::GetAllSupportedLayers()VulkanEnv::CreateVkInstance()运行代码先叨叨Vulkan为了尽量提高执行效率,因此所有API对传入的参数没有作任何校验。即使传错了参数也会继续执行,对错误参数会造成的后果不做任何定义。不过Vulkan也提供......
  • Python.拓展05
    Python.拓展051.缩进,用4个空格,不要用制表符。2.4个空格是小缩进(更深嵌套)和大缩进(更易阅读)之间的折中方案。制表符会引起混乱,最好别用。3.换行,一行不超过79个字符,这有助于在多种屏幕和设备上保持良好的可读性。4.这样换行的小屏阅读体验更好,还便于在大屏显示器上并排阅读......
  • Task05 && 拓展01
    Task05条件ConditionalsIF语句IFElse语句IF-ELIF-ELSE语句IF-ELSE推导式defabs7(n) returnnif(n>=0)else-ndefabs7(n):ifn>=0:returnnelse:return-nMATCH-CASE语句matchsubject: case<pattern_1> <action_1......