找到形成周期的图表中最重的边

时间:2017-12-24 12:38:50

标签: algorithm recursion graph max cycle

给定一个无向图,我想要一个算法(在O(|V|+|E|)中),它会找到形成一个循环的图中最重的边缘。例如,如果我的图表如下所示,并且我将运行DFS(A),则图表中最重的边缘将为BC。 (*)在这个问题上,我最多有1个周期。

enter image description here

我正在尝试编写一个修改后的DFS,它将返回所需的重边缘,但我遇到了一些麻烦。

因为我最多有一个循环,所以我可以将循环中的边缘保存在一个数组中,并在运行结束时轻松找到最大边缘,但我认为这个答案看起来有点乱,我就是确定有更好的递归答案。

2 个答案:

答案 0 :(得分:3)

我认为解决这个问题的最简单方法是以类似于Kruskal的MST算法的方式使用union-find数据结构(https://en.wikipedia.org/wiki/Disjoint-set_data_structure):

  1. 将每个顶点放在自己的集合中
  2. 按重量顺序迭代边缘。对于每条边,如果它们不在同一组中,则合并相邻顶点的集合。
  3. 请记住 last 边缘,您在其中发现其相邻顶点已经在同一个集合中。那是你正在寻找的那个。
  4. 这是有效的,因为您在任何周期中访问的 last 和最重的边必须已经通过您之前访问过的边连接其相邻顶点。

答案 1 :(得分:1)

使用Tarjan's Strongly Connected Components algorithm

将图形拆分为多个强连通图形后,为每个节点分配一个COMP_ID,指定该节点所属的组件ID(这可以通过对算法进行小编辑来完成。定义全局整数值从 1 开始。每次从堆栈中弹出节点时,它们都对应于同一个组件,将此变量的值保存到这些节点的COMP_ID。循环结束将此整数的值递增1)。

现在,迭代所有边缘。你有两种可能性:

  1. 如果此边缘链接来自两个不同组件的两个节点,则此边缘不能作为答案,因为它不可能是循环的一部分。

  2. 如果此边连接同一组件中的两个节点,则此边是某个循环的一部分。您现在要做的就是在类型2的所有边缘中选择最大边缘。

  3. 所描述的方法以O( | V | + | E | )的总复杂度运行,因为每个节点和边缘对应于至多一个强连接组件。

    在图表示例中,您提供的COMP_ID如下:

    • COMP_ID [ A ] = 1

    • COMP_ID [ B ] = 2

    • COMP_ID [ C ] = 2

    • COMP_ID [ D ] = 2

    Edge 10将COMP_ID 1 与COMP_ID 2 连接起来,因此无法解决问题。答案是边{2,5,8}中的最大值,因为它们都将COMP_ID 1 连接到自身,因此答案是 8