查找图是否具有唯一拓扑顺序的时间复杂度

时间:2015-04-09 19:28:19

标签: algorithm graph time-complexity graph-theory

我有这个算法来查找有向图是否具有唯一的拓扑顺序

  1. 初始化清单L
  2. 在此图中找到作为接收器的顶点V(sink =从中没有任何有序边的顶点)
  3. 从图表中删除所有进入V的边,然后是顶点V
  4. 将V添加到L
  5. 如果图表中还有顶点,请转到步骤2
  6. 最后,我在L中有顶点的拓扑顺序。如果我可以在步骤2中选择多个顶点,那么这个拓扑顺序不是唯一的。如果我在图表为空之前遇到任何这些步骤,则意味着该图表根本没有拓扑顺序。

    我认为这个算法的时间复杂度是O(n),其中n是图中顶点的数量,但显然这是不对的。

2 个答案:

答案 0 :(得分:1)

m为边数,n为顶点数。您的算法的简单实现是O(nm)。如果通过遍历可以执行O(m)次循环的n迭代的边集来实现步骤2。

但是,您可以按照以下时间复杂度O(n+m)执行此操作。我将假设一个顶点存储为一个整数,一个边存储为一对尾部和头部的整数。

步骤A

除了L之外,请初始化以下内容

(a)一个数组A,每个顶点有一个插槽。数组应为每个顶点i存储一个指向i的所有顶点的列表。

(b)汇总S个汇点(因此可以删除)。

(c)数组B,每个顶点也有一个插槽。此数组应存储每个顶点i 的边缘远离 i。当此数字降至零时,相应的顶点必须是接收器,因此可以添加到S

步骤B

首先迭代一组边。将每个边E: i -> j增加B[i]一个,并将E添加到列表A[j]。此迭代为O(m)

第C步

迭代数组B,如果B[i] == 0,请将i添加到堆栈S。这是O(m)

步骤D

步骤D是一个while循环

while (S is not empty) { 

i移除第一个接收器S并将其添加到L。因为您有一个列表A[i],所以您知道指向i的所有边。对于这些边缘中的每一个E: j-> i,通过从1中减去B[j]来删除边缘。如果B[j]的值已降至零,请将j添加到S

}.

在步骤D结束时,所有接收器都将被移除。步骤D为O(n+m),因为每个顶点最多被移除一次,每条边最多读取一次。

答案 1 :(得分:0)

没有指定数据结构,但选择好,运行时间为O(m + n),其中m是边数,n是顶点数。对于密集图,可能是m>> n,所以O(n)时间不足以读取整个图表。相反,如果图形断开,则可能是n>> m,所以大O内的两个术语都是必要的。