当前位置: 首页 > 知识库问答 >
问题:

具有未使用边的循环检测无向图

阎麒
2023-03-14

我有一个带边的无向图。每条边都具有一定的性质,如A点和B点之间的边之一是

{
travelTime :10hours
travelPath : air
}

在C点和D点之间的另一个可以是

{
travelTime :1hours
travelPath : Metro
} 

我们得到了这样一个图和已知的旅行路径

 {air, Metro,Rail, Bus ,Auto,Rickshaw  }

有快一点的吗?

共有1个答案

水飞掣
2023-03-14

由于您希望只检测metro边或rail边的循环,我们可以通过先运行metro边,然后运行rail边的算法来简化问题。因此,一个不需要不同边缘类的算法可以简单地适应于整个问题。

简化的问题可以使用不相交集数据结构的变化来解决。我们可以将固定的边插入到数据结构中,然后查询(不插入)每个新边。这告诉我们是否存在循环,但如果要恢复循环,我们需要增强数据结构。

在数据结构中维护两个父指针数组:一个是使用路径压缩的不交并数据结构的正常数组,另一个不使用路径压缩。没有路径压缩的图必须保持父指针树中的每个(有向)边都是原始图的(无向)边的不变性质;这意味着有时需要翻转边的方向,以便为联合操作重新根树。

当测试非固定边时,我们使用路径压缩数组来查询是否存在循环,如果存在,我们通过将另一个数组中的两个顶点跟随到它们在父指针树中的最低公共祖先来恢复循环。这起作用是因为未压缩数组中的边都是来自原始固定图的边,而包含未固定边的循环可以从该边加上从其每个顶点到共同祖先的两条路径形成。

在最坏的情况下,总运行时间为O(ma(v)+v²+nv),其中v是顶点数,m是固定边数,n是非固定边数,a是非常缓慢增长的逆阿克曼函数。

>

  • m(v)项是union-find数据结构上O(m)个“find”查询的代价。还有另外一个O(n)个“find”查询被执行,但这些查询的术语主要是NV。

    v²term是在未压缩数组中重新根树的成本,最多为O(v)次,在最坏的情况下,每次翻转最多为O(v)条边。

    nv项是最坏情况下输出的大小;最多可以有n个周期,且每个周期的长度最多可以为v。如果大多数非固定边沿不产生周期,且/或周期通常相对于v较短,则运行时间将显著加快。在这个意义上,该算法是输出敏感的。

  •  类似资料:
    • 目前我正在用这个样本进行拓扑排序,并对https://www.geeksforgeeks.org/topological-sorting/做了一些修改 我用它来排序要求解的变量的顺序。 样本 每个变量都有一个唯一整数,并存储在一个映射中 创建图形并添加边时,总共有4个顶点,因此我的代码将像这样构造图形 排序并按相反顺序得到结果后,它是正确的c 一切都很好,但我需要检测图中的循环引用。假设变量是 有

    • 我在这里读到一篇关于在有向图中求圈的讨论。现在,OP声称我们需要验证两件事: 从到有一个后沿 在递归堆栈中 为什么我们需要第二次测试?你能举个例子来说明它的必要性吗?

    • 因此,我为DFS编写了以下代码: 现在,我读到,在一个无向图中,如果当DFS时,它再次返回到同一个顶点,有一个循环。所以我做的是这样,, 但是,我的检查周期函数返回true,即使他们没有周期。那是为什么呢?我的功能有问题吗?没有执行问题,否则我早就调试了,但他们似乎在我的逻辑中有问题。

    • 我有一个无向图,它被加载为邻接矩阵。我有一个使用BFS算法检测图中循环的方法。我试图实现的是打印所有的边缘,以一种方式,他们表明一个循环,已经找到。 我可以打印一个图形中的所有边,但我不能只打印那些创建循环的边。我怎么让它工作? 边缘: 图表: 节点: 当前错误输出:显示一个周期的部分边沿,但不是全部边沿 预期输出:打印创建循环的所有边,如上面的示例所示, 我想显示:一条边的结束顶点是循环中另一条

    • 另一个问题只回答了如何检测一个周期,而不是输出它。所以,我想在一个无向图上写一个算法,在O(V+E)时间内运行BFS或DFS(V=顶点,E=边),如果有循环,则输出循环。 到目前为止,我所知道的是BFS/DFS是如何工作的,如果访问已经标记为已访问的节点,可以使用BFS检测周期。

    • 我试图用BFS算法在有向图中检测循环。我检测周期的主要想法是:由于BFS只访问每个节点(和边缘)一次,如果我再次遇到已访问的节点;它会导致一个循环。然而,我的代码有时会找到循环,有时不会。 我从维基百科修改的伪代码如下: 我错过了什么?