- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个无向连通图G。我希望找到一个算法,如果至少有2个MST,则返回true。
如果我想看看是否有2个MST,该怎么办?
最佳答案
通过修改Kruskal算法,我们可以有效地检测这两种情况。如果有人可以想到一种更简单的方式来描述所有这一切,请告诉我!
Kruskal为等权重边缘的每个排列构建一个MST
Kruskal算法通过始终包含连接到目前已构建的森林的不同组件的第二个最小边缘来构建MST。每当选择任何这样的最小边缘时,即不管如何排序具有相等权重的边缘,该算法都是正确的。
克鲁斯卡尔可以找到每个MST
此外,可以通过选择某种特定方式对每组等权重边进行排序,然后运行Kruskal算法来生成每个MST。看到这一点,假设有些MST无法通过这种方式产生。现在,从此MST中每个边的权重中减去一些少量的epsilon(小于任何一对不相等的边权重之间的差):此MST现在是唯一的MST,因此,当使用新的边权重运行时,Kruskal必须产生此MST 。但是因为我们最多只能调整epsilon的边缘,所以当按权重对边缘进行排序时,所有具有权重w_i的边缘集-epsilon必须出现(以某种顺序)紧接在具有权重w_i的边缘集(某种顺序)之前,两组之间没有其他边缘。但这对于原始的未修改边缘是有效的可能排序,并且Kruskal算法只关心边缘的排序,而不关心它们的特定权重,因此Kruskal算法也必须从该排序中产生MST。这与我们的假设相矛盾,因此必须是Kruskal算法可以产生每个MST。
组件图
在i> = 0边累加步骤F(i)之后,调用由Kruskal算法构建的森林,剩下的边需要考虑,并且不会创建循环R(i)。 (当在步骤i中添加一条边时,我们从R(i-1)的副本开始并删除刚添加的边和连接同一对组件的所有其他边来形成R(i)。尽管Kruskal算法实际上“偷懒”地消除了这些其他边,从而定义R(i)简化了证明算法的性质。)我们将把Kruskal算法分解为一系列块,每个块由一系列边加法组成,其中边的边添加相同的重量。如果i = 0或R(i)中的最小权重边缘大于在步骤1 .. i中添加的任何边缘,则调用i块定义。
假设在执行了Kruskal算法的边加法步骤的某些块定义数i> = 0之后,R(i)中的最小边(即,不会创建循环的下一个最小边)的权重为w 。在执行其他任何操作之前,Kruskal算法将以某种方式继续将它们之间具有权重w边缘的所有树合并在一起,即使为这些等权重的边缘选择不同的边缘顺序可以影响生成的树,也不会影响每棵树中的一组顶点。使其更加精确:
定义一个新的,未加权的多重图(即在一对顶点之间可以具有多个边的图)C(i),其中包含森林F(i)中每个组件(树)的顶点。对于C(i)中的任何顶点v,请调用t(v)F(i)中与v对应的树。每当R(i)中存在权重w边时,在C中在两个顶点u和v之间创建边在t(u)中的某个顶点和t(v)中的某些顶点之间。在i步之后调用C(i)组件图。
引理:假设对于某些块定义数字i,C(i)具有k个包含至少1个边的分量(即,不是单个顶点的分量),并且在这些分量中总共有m> = 2k个顶点。将这组顶点称为M。然后,不管等权重边缘的排序方式如何,在Kruskal算法增加了mk个边缘相加步骤之后,与M中的顶点相对应的m棵树将合并为k棵树,第j个树由与C(i)的第j个分量的顶点相对应的树的并集加上一个或多个权重w的边组成,每1 <= j <= k。特别是,在k个结果树中的每一个中,一组顶点不受权重w边的特定排序的影响,该排序导致C(i)中的边。
证明:C(i)中的每个边缘(u,v)对应于R(i)中的权重w边缘,它在等权重边缘的某些排列中可能首先出现在所有权重w边缘中,因此可以选择接下来是Kruskal算法。相加的效果是将F(i)中的两棵树连接在一起成为F(i + 1)中的一棵树,并丢弃R(i + 1)中的一个或多个边。对分量图的影响是将C(i)中的u和v合并为C(i + 1)中的单个顶点x,删除C(i + 1)中u和v之间的所有其他平行边,然后更改C(i)中第三个顶点y和u或v之间的所有边都变成C(i + 1)中y和新顶点x之间的边。如果Kruskal接下来选择C(i)的一个分量中的边,则其他分量的边不受影响,因此如何在排列中交错不同分量的边。因此,我们可以假设首先看到一个组件的所有边缘,然后看到另一个组件的所有边缘,依此类推,直到第k个组件。假设第一个分量具有s个顶点。通过Kruskal算法添加的每个边都会将此组件的顶点数量减少1,而无需断开组件的连接。 C(i + j)中组件中存在边缘表示R(i + j)中存在权重w边缘,该边缘连接F(i + j)中的两个不同树,因此Kruskal算法将继续选择缩小该分量的边缘,直到它变成C(i + s-1)中的单个顶点。无论在每个步骤中选择了哪个边,F(i + s-1)中相应树中的顶点都将包含F(i)中s树中所有顶点的并集。其余组件可以重复此操作。如果总共有k个组件之间有m个顶点,则需要m-k个步骤才能将每个组件缩小到单个顶点。
计算MST
定理:MST的数量是每个块定义i的多图C(i)中生成林的数量的乘积。
证明:如在引理中所确定的,在F(i + m-k)中每个结果树分量的顶点集上,通过在C(i)中的边的某些排列上运行Kruskal可以产生的每个森林都是相同的。 C(i)的s顶点分量的每个生成树代表一组不同的s-1边,可以通过Kruskal算法选择它们,以生成包含F(i)中相应的s树集合的独特底层MST。 。生成林是生成树的组合,每个组成部分一个,因此生成林的数量是每个包含的树的生成树数量的乘积。称C(i)q(i)中的成林数。由于后续Kruskal块中的边缘加法步骤并不关心每个组件的边缘结构,而仅关心每个组件中的顶点,因此,从步骤i开始的块的q(i)生成林的任何选择都不会影响从步骤j> i开始的下一个块的跨林数量,并且所有q(i)* q(j)森林都是不同的。
用于计算图的生成树数量的算法有些复杂,例如基于Kirchhoff's theorem,given by imslavko的算法。我不确定那是否适用于多图。但是无论如何,由于我们只关心1、2和2以上的特殊情况,因此可以采用捷径。
如果我们只想检测图是否正好是1个MST或大于1,则可以使用以下事实:整数乘积等于1的唯一方法是每个因子等于1:即是否有任何块对于C(i)具有超过1个生成树,请立即停止并报告“大于1”。如果没有发生这种情况,请报告“ 1”。
如果我们要检测图是否具有精确的2个MST,则可以使用以下事实:对于等于2的整数乘积,恰好其中一个因子必须等于2,其余所有因子必须等于1。 multigraph要有2个生成树,它必须由一个森林加上两个顶点之间正好有一个边的正好一个附加(平行)边组成。 (任何包含k> = 3的k循环的多图必须至少有k个生成树,通过删除k个边中的任意一个形成。)
算法概述
照常执行Kruskal,但是只要有新的块开始(由添加的权重大于以前添加的边缘的边表示),在添加边缘之前,请执行以下步骤:
使用邻接表表示创建一个空的多重图形C。
向前扫描具有此权重的所有其余边缘,并为每个边缘(u,v)将(c(u),c(v))添加到C,其中c(v)是联合发现的v的代表性节点/ find结构用于检查连通性。
通过使用一组标志来记录已访问过哪些顶点,通过此Multigraph的每个组件执行DFS。此DFS的目的是检查循环和平行边:
如果有任何长度为3或更高的循环,则该组件至少具有3个生成树,这意味着算法可以在此点终止。
如果出现平行度大于或等于3的平行边,该算法同样可以立即终止。
每次在两个顶点之间看到双边时,都增加一个全局计数器:如果此计数器大于1,则至少存在2 * 2 = 4个MST,因此算法可以立即终止。如果我们到达Kruskal算法的末尾,并且计数器为1,则确切地存在2个MST。否则,它必须为0,在这种情况下恰好存在1个MST。
所有这些附加操作在不相交的边块上花费线性时间,因此它们不会增加基础Kruskal算法的时间复杂度超过O(E log V)。
关于algorithm - 一种算法,看看图中是否恰好有两个MST?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13751582/
我在一本书(Interview Question)中读到这个问题,想在这里详细讨论这个问题。请点亮它。 问题如下:- 隐私和匿名化 马萨诸塞州集团保险委员会早在 1990 年代中期就有一个绝妙的主意
我最近接受了一次面试,面试官给了我一些伪代码并提出了相关问题。不幸的是,由于准备不足,我无法回答他的问题。由于时间关系,我无法向他请教该问题的解决方案。如果有人可以指导我并帮助我理解问题,以便我可以改
这是我的代码 public int getDist(Node root, int value) { if (root == null && value !=0) return
就效率而言,Strassen 算法应该停止递归并应用乘法的最佳交叉点是多少? 我知道这与具体的实现和硬件密切相关,但对于一般情况应该有某种指南或某人的一些实验结果。 在网上搜索了一下,问了一些他们认为
我想学习一些关于分布式算法的知识,所以我正在寻找任何书籍推荐。我对理论书籍更感兴趣,因为实现只是个人喜好问题(我可能会使用 erlang(或 c#))。但另一方面,我不想对算法进行原始的数学分析。只是
我想知道你们中有多少人实现了计算机科学的“ classical algorithms ”,例如 Dijkstra's algorithm或现实世界中的数据结构(例如二叉搜索树),而不是学术项目? 当有
我正在解决旧编程竞赛中的一些示例问题。在这个问题中,我们得到了我们有多少调酒师以及他们知道哪些食谱的信息。制作每杯鸡尾酒需要 1 分钟,我们需要使用所有调酒师计算是否可以在 5 分钟内完成订单。 解决
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 8 年前。 Improve
我开始学习 Nodejs,但我被困在中间的某个地方。我从 npm 安装了一个新库,它是 express -jwt ,它在运行后显示某种错误。附上代码和错误日志,请帮助我! const jwt = re
我有一个证书,其中签名算法显示“sha256rsa”,但指纹算法显示“sha1”。我的证书 SHA1/SHA2 的标识是什么? 谢谢! 最佳答案 TL;TR:签名和指纹是完全不同的东西。对于证书的强度
我目前在我的大学学习数据结构类(class),并且在之前的类(class)中做过一些算法分析,但这是我在之前的类(class)中遇到的最困难的部分。我们现在将在我的数据结构类(class)中学习算法分
有一个由 N 个 1x1 方格组成的区域,并且该区域的所有部分都是相连的(没有任何方格无法到达的方格)。 下面是一些面积的例子。 我想在这个区域中选择一些方块,并且两个相邻的方块不能一起选择(对角接触
我有一些多边形形状的点列表,我想将其包含在我页面上的 Google map 中。 我已经从原始数据中删除了尽可能多的不必要的多边形,现在我剩下大约 12 个,但它们非常详细以至于导致了问题。现在我的文
我目前正在实现 Marching Squares用于计算等高线曲线,我对此处提到的位移位的使用有疑问 Compose the 4 bits at the corners of the cell to
我正在尝试针对给定算法的约束满足问题实现此递归回溯函数: function BACKTRACKING-SEARCH(csp) returns solution/failure return R
是否有包含反函数的库? 作为项目的一部分,我目前正在研究测向算法。我正在使用巴特利特相关性。在 Bartlett 相关性中,我需要将已经是 3 次矩阵乘法(包括 Hermitian 转置)的分子除以作
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭 8 年前。 Improve
问题的链接是UVA - 1394 : And There Was One . 朴素的算法是扫描整个数组并在每次迭代中标记第 k 个元素并在最后停止:这需要 O(n^2) 时间。 我搜索了一种替代算法并
COM 中创建 GUID 的函数 (CoCreateGUID) 使用“分散唯一性算法”,但我的问题是,它是什么? 谁能解释一下? 最佳答案 一种生成 ID 的方法,该 ID 具有一定的唯一性保证,而不
在做一个项目时我遇到了这个问题,我将在这个问题的实际领域之外重新措辞(我想我可以谈论烟花的口径和形状,但这会使理解更加复杂).我正在寻找一种(可能是近似的)算法来解决它。 我有 n 个不同大小的容器,
我是一名优秀的程序员,十分优秀!