我有很多周期(用数值表示,例如,1-2-3-4
对应一个周期,有4个边,边1
是{1:2}
,边{{1} }是2
,边{2:3}
是3
,边{3,4}
是4
,依此类推。)
如果一个循环共享一个且只有一个边缘,则称该循环连接到另一个循环。
例如,假设我有两个周期{4,1}
和1-2-3-4
,那么有两个周期组,因为这两个周期没有相互连接。如果我有两个周期5-6-7-8
和1-2-3-4
,那么我只有一个周期组,因为这两个周期共享相同的边。
下图应该可以说明我的观点:
alt text http://lh5.ggpht.com/_SDci0Pf3tzU/SuBhd07xbWI/AAAAAAAAFMs/9OlMhN8uzzQ/s640/mst.jpg
3-4-5-6
,R1
到R2
就是我所说的“周期”。在上图中,只有一个循环组包含所有R7
到R1
。
查找所有循环组的最有效方法是什么?
答案 0 :(得分:3)
首先找到图中的所有周期并将它们标记为例如A,B,C等。现在创建一个新图,其中图中找到的每个周期都转换为新图中的单个节点。如果相应的周期在旧图中“连接”,则使用您的(相当不寻常的)连接定义,在新图表中加入边缘加入。
“循环组”的数量是新图表中connected components的数量。
答案 1 :(得分:0)
我很确定,这不是最有效的方式,但这是我最初的尝试:
首先使用顶点交换边:因此,对于您的示例周期1-2-3-4
,3-4-5-6
和5-6-7-8
,您需要:
"12" => "A"
"23" => "B"
"34" => "C"
"45" => "D"
"56" => "E"
"67" => "F"
"78" => "G"
"41" => "H"
"63" => "I"
"85" => "J"
这为你提供了最多(v *(v-1))/ 2个顶点,但没关系 - 对于O(v ^ 2)算法来说它仍然足够好。
然后将周期表示为位域: “1-2-3-4”成为ABCH
ABCDEFGHIJ
1110000100
和“3-4-5-6”成为CDEI
ABCDEFGHIJ
0011100010
所以他们只有一点共同点,这意味着在原始图中,它们只有一个共同的边缘。这可以用O(v ^ 2)逐位检查,或者用二进制搜索检查(首先通过ANDing检查,如果它们有任何共同点,那么检查AND的前半部分等等。)