给定一个无向图,我想要一个算法(在O(|V|+|E|)
中),它会找到形成一个循环的图中最重的边缘。例如,如果我的图表如下所示,并且我将运行DFS(A)
,则图表中最重的边缘将为BC
。
(*)在这个问题上,我最多有1个周期。
我正在尝试编写一个修改后的DFS,它将返回所需的重边缘,但我遇到了一些麻烦。
因为我最多有一个循环,所以我可以将循环中的边缘保存在一个数组中,并在运行结束时轻松找到最大边缘,但我认为这个答案看起来有点乱,我就是确定有更好的递归答案。
答案 0 :(得分:3)
我认为解决这个问题的最简单方法是以类似于Kruskal的MST算法的方式使用union-find数据结构(https://en.wikipedia.org/wiki/Disjoint-set_data_structure):
这是有效的,因为您在任何周期中访问的 last 和最重的边必须已经通过您之前访问过的边连接其相邻顶点。
答案 1 :(得分:1)
使用Tarjan's Strongly Connected Components algorithm。
将图形拆分为多个强连通图形后,为每个节点分配一个COMP_ID
,指定该节点所属的组件ID(这可以通过对算法进行小编辑来完成。定义全局整数值从 1 开始。每次从堆栈中弹出节点时,它们都对应于同一个组件,将此变量的值保存到这些节点的COMP_ID
。循环结束将此整数的值递增1)。
现在,迭代所有边缘。你有两种可能性:
如果此边缘链接来自两个不同组件的两个节点,则此边缘不能作为答案,因为它不可能是循环的一部分。
如果此边连接同一组件中的两个节点,则此边是某个循环的一部分。您现在要做的就是在类型2的所有边缘中选择最大边缘。
所描述的方法以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